使用Database.Create时出现“dbo.__MigrationHistory”无效的对象名称;当传递连接字符串时,EF6.02会发生这种情况。

38

当我尝试使用以下代码创建数据库时,遇到了错误。 请注意,如果未传递连接字符串,则不会出现问题。 同时,当我在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();

我在这里找到了一些文档,但它让我感到困惑。我正在安装一个“稳定版本”,难道我还会遇到2012年的问题吗?我在使用PM时做错了什么?

该问题的错误消息是...

System.Data.Entity.Core.EntityCommandExecutionException出现
HResult=-2146232004 Message=执行命令定义时发生错误。有关详细信息,请参见内部异常。
Source=EntityFramework StackTrace: at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) InnerException: System.Data.SqlClient.SqlException HResult=-2146232060 Message=无效的对象名称 '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:


当你调试应用程序时,是否偶尔会看到这个异常,但是在没有连接调试器的情况下运行应用程序时却看不到它? - Pawel
没错。我已经更新了问题并添加了这些信息。 - Kirsten
任何遇到类似问题的人都可以使用以下链接:https://forums.asp.net/t/2133118.aspx?How+to+ignore+or+stop+creating+table+from+class+EF+code+first - Phil3992
6个回答

80
这是因为EF会探测__MigrationsHistory表。例如,您可以使用EF与不使用EF迁移创建的现有数据库,但EF无法知道它,因此尝试连接到数据库并使用表来检查。如果表不存在,则会抛出异常。EF然后捕获异常并执行正确的操作(例如,如果需要,则创建__MigrationsHistory表或继续不使用迁移)。通常情况下,在没有调试器的情况下运行时,您不会看到此异常。但是,当调试代码且设置了在引发异常时中断执行选项时,即使内部处理并且从未到达您的代码,您也会看到所有引发的异常。默认设置是在引发未经处理的异常时中断,而不是在引发异常时中断。您可以通过在Debug->Exceptions对话框中检查/取消选中“Thrown”列中的复选框来更改设置。在VS 2017中,您可以使用Debug->Windows->Exception Settings打开异常设置。如果右键单击“Common Language Runtime Exceptions”,则可以选择“还原默认值”,从而禁用大多数异常引发程序中断。

2
谢谢,我会检查的。我的项目中没有迁移文件夹,所以它试图创建表格是令人困惑的。 - Kirsten
1
正如我在评论中所说的那样 - 右键单击“Common Language Runtime Exceptions”并选择“恢复默认值”。这将禁用在抛出但已处理的异常时中断。调试器仍会在抛出但未处理的异常时中断。 - Pawel
1
这是一种“System.Data.SqlClient.SqlException”类型的异常。如果我们从异常设置中禁用它,那么我们会丢失所有定义的SqlException代码吗? - Teoman shipahi
2
谢谢这个信息,它很有用,因为应用洞察仍在监视此异常。 - Christian van R
1
谢谢,我们的一位开发人员对这个在这台机器上无法工作感到非常疯狂。 - Wiktor Zychla
显示剩余10条评论

19

通过在您的上下文构造函数中添加以下内容,您可以关闭代码优先数据库初始化:

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

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


System.Data.Entity.Database.SetInitializer<YourContext>(null); - Jared Beach
@JaredBeach 是 EF.Core 的版本吗?我记不得它的语法了。 - Danny Varod
正则 EF。上下文中有一个名为“Database”的属性。实际上,您需要的是Database类型。顺便感谢您的帮助。 - Jared Beach

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

0

我使用的数据库表 __MigrationHistory 丢失了,所以当我脚本化迁移时,它生成了这段代码:

IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
    CREATE TABLE [__EFMigrationsHistory] (
        [MigrationId] nvarchar(150) NOT NULL,
        [ProductVersion] nvarchar(32) NOT NULL,
        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
    );
END;

这个已经修复了。


0

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


0

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

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接