Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
759 views
in Technique[技术] by (71.8m points)

entity framework 6 - Invalid object name 'dbo.__MigrationHistory' using Database.Create; EF6.02 when connection string is passed in

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:

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...