35
votes

I experience an error when trying to create a database using the following code. Note the problem does not happen if the connection string is not passed in. Also the problem happens when I run the program in the IDE. It does not happen if I run the program .exe or if I run the unit tests within the IDE.

However if the database is created by running the unit tests or by running the .EXE then the __MigrationHistory table is created in the main tables section, not the system tables.

public Context(string connString, bool AddInitialRecords )
    : base(connString ?? "MyContextName")
{
    this.CheckDatabase(AddInitialRecords);
}

public void CheckDatabase(bool AddInitialRecords)
{
    if (this.Database.Exists())
    {
         // upgrade stuff
    }
    else
    {
       Database.Create();  // error occurs here
        // seeding stuff 
    }
}

I don't get the problem if I just use something like

var db1 = new Context();
db1.Database.CreateIfNotExists();

I have found some documentation here but it confuses me. I am installing from a "stable build" surely I aren't experiencing something from 2012? What could I be doing wrong with PM?

The error message for the problem is....

System.Data.Entity.Core.EntityCommandExecutionException occurred
HResult=-2146232004 Message=An error occurred while executing the command definition. See the inner exception for details.
Source=EntityFramework StackTrace: at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) InnerException: System.Data.SqlClient.SqlException HResult=-2146232060 Message=Invalid object name 'dbo.__MigrationHistory'. Source=.Net SqlClient Data Provider ErrorCode=-2146232060 Class=16 LineNumber=1 Number=208 Procedure="" Server=.\SQLEXPRESS State=1 StackTrace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.b__8() at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](Func`1 operation, TInterceptionContext interceptionContext, Action`1 executing, Action`1 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) InnerException:

4
Do you by any chance see this exception when debugging the application but you do not see it when running the app without the debugger attached?Pawel
That is correct. I updated the question with the information.Kirsten Greed
Useful link for anyone having a simlar issue forums.asp.net/t/…Phil3992

4 Answers

76
votes

This happens because EF does some probing for the __MigrationsHistory table. For instance you can use EF with an existing database that was not created using EF Migrations but EF has no way of knowing it so it tries to connect to the database and uses the table to check this. If the table does not exist an exception will be thrown. EF then catches the exception and does the right thing (e.g. creates the __MigrationsHistory table if needed or proceeds without using migrations).

In general you won't see this exception when running without the debugger. However when debugging your code AND when the option to break the execution when an exception is thrown is set you will see all the exceptions that are being thrown even if they are internally handled and never reach your code. The default setting is not to break when the exception is thrown but only when an exception that is not being handled is thrown. You can change the setting by checking/unchecking a check box in the "Thrown" column in the Debug -> Exceptions dialog.

In VS 2017 you open exception settings using Debug->Windows->Exception Settings. If you right-click on the "Common Language Runtime Exceptions" you can select the "Restore Defaults" which disables breaking your program when most of the exceptions are thrown.

16
votes

You can turn off code first database initialization for your database, by adding this to your context's constructor:

System.Data.Entity.Database.SetInitializer<YourContext>(null);

This should prevent the attempt to access dbo.__MigrationHistory.

1
votes

I faced the same issue. It means that EF is not able to find the __Migration history table. also note for some reason it has to be dbo.__MigrationHistory (note dbo). Ensure that you have run "update-database" atleast once before running the Context

0
votes

I forgot to add the database name in my connection string. After I added, it started to work