尝试使用以下代码创建数据库时遇到错误。 请注意,如果未传入连接字符串,则不会发生此问题。 当我在IDE中运行程序时,问题也会发生。如果我运行程序.exe或者在IDE中运行单元测试,则不会发生这种情况。
但是,如果通过运行单元测试或运行.EXE创建数据库,则会在主表部分创建__MigrationHistory
表,而不是系统表。
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
}
}
如果我只是使用像
这样的东西,我就不会遇到问题var db1 = new Context();
db1.Database.CreateIfNotExists();
我找到了一些文档here,但它让我感到困惑。我是从“稳定的版本”安装的,我肯定没有遇到过2012年的东西? PM怎么办?
问题的错误消息是......
发生了System.Data.Entity.Core.EntityCommandExecutionException HResult = -2146232004消息=执行时发生错误 命令定义。有关详细信息,请参阅内部异常 Source = EntityFramework StackTrace: 在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand) entityCommand,CommandBehavior behavior)InnerException: System.Data.SqlClient.SqlException 的HResult = -2146232060 消息=无效的对象名称'dbo .__ MigrationHistory'。 Source = .Net SqlClient数据提供程序 错误码= -2146232060 类= 16 LineNumber上= 1 数= 208 过程=“” 服务器=。\ SQLEXPRESS 状态= 1 堆栈跟踪: 在System.Data.SqlClient.SqlConnection.OnError(SqlException异常, Boolean breakConnection,Action`1 wrapCloseInAction) 在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject) stateObj,Boolean callerHasConnectionLock,Boolean asyncClose) 在System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,布尔& dataReady) 在System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() 在System.Data.SqlClient.SqlDataReader.get_MetaData() 在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior,String resetOptionsString) 在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async,Int32超时,任务& task,Boolean asyncWrite) 在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法,TaskCompletionSource`1完成,Int32超时,任务&任务, 布尔asyncWrite) 在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法) 在System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法) 在System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为) 在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher。<> c__DisplayClassb.b__8() 在System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch [TInterceptionContext,TResult](Func`1 operation,TInterceptionContext interceptionContext,Action`1 执行,执行Action`1) 在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand) command,DbCommandInterceptionContext interceptionContext) 在System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior) 行为) 在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand) entityCommand,CommandBehavior行为) 的InnerException:
答案 0 :(得分:67)
这是因为EF对__MigrationsHistory表进行了一些探测。例如,您可以将EF与未使用EF迁移创建的现有数据库一起使用,但EF无法知道它,因此它尝试连接到数据库并使用该表进行检查。如果该表不存在,则抛出异常。然后EF捕获异常并做正确的事情(例如,如果需要,则创建__MigrationsHistory表,或者不使用迁移继续)。
通常,在没有调试器的情况下运行时,您不会看到此异常。但是,当调试代码 AND 时,如果设置了在抛出异常时中断执行的选项,您将看到所有异常,即使它们是内部处理且永远不会到达您的代码,也会被抛出。抛出异常时,默认设置不会中断,但仅在抛出未处理的异常时才会中断。您可以通过选中/取消选中Debug - >中“Thrown”列中的复选框来更改设置。例外对话框。
在VS 2017中,您可以使用Debug-> Windows-> Exception Settings打开例外设置。如果右键单击“公共语言运行时异常”,则可以选择“恢复默认值”,以便在抛出大多数异常时禁用破坏程序。
答案 1 :(得分:9)
您可以通过将此数据库初始化添加到您的上下文的构造函数来关闭代码的数据库初始化:
Database.SetInitializer<YourContext>(null);
这可能会阻止尝试访问dbo.__MigrationHistory
。
答案 2 :(得分:1)
我遇到了同样的问题。这意味着EF无法找到__Migration历史表。还注意到它必须是dbo .__ MigrationHistory(注意dbo)。确保您已运行&#34; update-database&#34;在运行Context
之前至少一次答案 3 :(得分:0)
我忘记在连接字符串中添加数据库名称。添加后,它开始起作用