使用 Database.Create 的对象名称“dbo.__MigrationHistory”无效;传入连接字符串时的EF6.02

Posted

技术标签:

【中文标题】使用 Database.Create 的对象名称“dbo.__MigrationHistory”无效;传入连接字符串时的EF6.02【英文标题】:Invalid object name 'dbo.__MigrationHistory' using Database.Create; EF6.02 when connection string is passed in 【发布时间】:2014-01-19 13:15:07 【问题描述】:

我在尝试使用以下代码创建数据库时遇到错误。 请注意,如果未传入连接字符串,则不会发生此问题。 当我在 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 消息=执行 命令定义。有关详细信息,请参阅内部异常。 来源=EntityFramework StackTrace: 在 System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior 行为)InnerException: System.Data.SqlClient.SqlException H结果=-2146232060 消息=无效的对象名称 'dbo.__MigrationHistory'。 Source=.Net SqlClient 数据提供者 错误代码=-2146232060 班级=16 行号=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 数据流, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean & dataReady) 在 System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior,字符串 resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、布尔 returnStream、布尔 异步,Int32 超时,任务和任务,布尔 asyncWrite) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法,TaskCompletionSource`1 完成,Int32 超时,Task& 任务, 布尔异步写入) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法) 在 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 操作,TInterceptionContext,interceptionContext,Action`1 正在执行,Action`1 已执行) 在 System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand 命令,DbCommandInterceptionContext 拦截上下文) 在 System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand、CommandBehavior 行为) 内部异常:

【问题讨论】:

您在调试应用程序时是否有机会看到此异常,但在未连接调试器的情况下运行应用程序时看不到它? 没错。我用信息更新了问题。 对遇到类似问题的人有用的链接forums.asp.net/t/… 【参考方案1】:

发生这种情况是因为 EF 对 __MigrationsHistory 表进行了一些探测。例如,您可以将 EF 与不是使用 EF 迁移创建的现有数据库一起使用,但 EF 无法知道它,因此它会尝试连接到数据库并使用表来检查这一点。如果表不存在,将抛出异常。然后 EF 捕获异常并做正确的事情(例如,如果需要,创建 __MigrationsHistory 表,或者在不使用迁移的情况下继续)。

一般来说,在没有调试器的情况下运行时您不会看到此异常。但是,当调试您的代码AND时,当设置了在抛出异常时中断执行的选项时,您将看到所有正在抛出的异常,即使它们是在内部处理的并且永远不会到达您的代码。默认设置是在抛出异常时不中断,而仅在抛出未处理的异常时才中断。您可以通过选中/取消选中 Debug -> Exceptions 对话框中“Thrown”列中的复选框来更改设置。

在 VS 2017 中,您可以使用 Debug->Windows->Exception Settings 打开异常设置。如果您右键单击“公共语言运行时异常”,您可以选择“恢复默认值”,这会在大多数异常被抛出时禁用您的程序。

【讨论】:

谢谢,我会检查的。我在项目中没有 Migrations 文件夹 - 所以它为什么要尝试制作表格令人困惑。 正如我在评论中所说 - 右键单击​​ Common Language Runtime Exceptions 并选择 Restore Defaults。当异常被抛出但被处理时,这将禁用中断。调试器仍会因抛出但未处理的异常而中断。 这是一个“System.Data.SqlClient.SqlException”类型的异常。如果我们从异常设置中禁用它,我们不会丢失所有定义的 SqlException 代码吗? 感谢此信息,这很有用,因为应用程序洞察仍在监视此异常 谢谢,我们的一位开发人员因为无法在这台机器上工作而发疯了。【参考方案2】:

您可以通过将其添加到上下文的构造函数中来关闭数据库的代码优先数据库初始化:

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

这应该可以防止尝试访问dbo.__MigrationHistory

【讨论】:

System.Data.Entity.Database.SetInitializer(null); @JaredBeach 是 EF.Core 版本 - 不记得它的语法了吗? 常规 EF。上下文中有一个名为“数据库”的属性。您实际上想要 Database 类型。顺便谢谢你的帮助【参考方案3】:

我遇到了同样的问题。这意味着 EF 无法找到 __Migration 历史记录表。还要注意由于某种原因它必须是 dbo.__MigrationHistory(注意 dbo)。确保在运行 Context 之前至少运行过一次“update-database”

【讨论】:

【参考方案4】:

我忘记在我的连接字符串中添加数据库名称。我添加后,它开始工作了

【讨论】:

【参考方案5】:

只需取消选中中断复选框,然后单击启用编辑以继续

【讨论】:

以上是关于使用 Database.Create 的对象名称“dbo.__MigrationHistory”无效;传入连接字符串时的EF6.02的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB“评估”执行顺序

EF 代码优先 - 删除然后创建数据库后播种

使用 MYSQL 在 ASP.NET MVC 上创建数据库模型

使用对象名称更改对象

symfony2.无法加载 pdo 驱动程序

为啥我们通常使用 plt 而不是对象的名称? [关闭]