如何在Entity Framework 4.3 Code First中禁用使用__MigrationHistory表?

11

我正在使用具有自定义数据库初始化程序的Entity Framework 4.3 Code First,代码如下:

public class MyContext : DbContext
{
    public MyContext()
    {
        Database.SetInitializer(new MyContextInitializer());
    }
}

public class MyContextInitializer : CreateDatabaseIfNotExists<MyContext>
{
    protected override void Seed(MyContext context)
    {
        // Add defaults to certain tables in the database

        base.Seed(context);
    }
}
每当我的模型更改时,我都会手动编辑我的 POCO 类和映射,并手动更新数据库。重新运行应用程序后,我会遇到以下错误:

'/' 应用程序中的服务器错误。

自创建数据库以来,“MyContext”上下文的支持模型已更改。考虑使用 Code First Migrations 更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。

描述:在当前 Web 请求执行过程中发生未处理的异常。有关该错误的更多信息和其代码原始位置,请查看堆栈跟踪。

异常详细信息:System.InvalidOperationException:自创建数据库以来,“MyContext”上下文的支持模型已更改。考虑使用 Code First Migrations 更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。

使用 EFProfiler,我还注意到这些查询正在被执行:
-- statement #1
SELECT [GroupBy1].[A1] AS [C1]
FROM   (SELECT COUNT(1) AS [A1]
        FROM   [dbo].[__MigrationHistory] AS [Extent1]) AS [GroupBy1]

-- statement #2
SELECT TOP (1) [Project1].[C1]          AS [C1],
               [Project1].[MigrationId] AS [MigrationId],
               [Project1].[Model]       AS [Model]
FROM   (SELECT [Extent1].[MigrationId] AS [MigrationId],
               [Extent1].[CreatedOn]   AS [CreatedOn],
               [Extent1].[Model]       AS [Model],
               1                       AS [C1]
        FROM   [dbo].[__MigrationHistory] AS [Extent1]) AS [Project1]
ORDER  BY [Project1].[CreatedOn] DESC

我该如何防止这种情况发生?

2个回答

10

起初,我认为问题是因为你在构造函数中设置了默认的初始化器,但是经过一番调查,我发现当创建上下文时,并不会运行该初始化器,而是在首次查询/添加时才会运行。

提供的初始化器都检查模型兼容性,所以你无法使用它们。不过,你可以像这样轻松地制作自己的初始化器:

 public class Initializer : IDatabaseInitializer<Context>
    {

        public void InitializeDatabase(Context context)
        {
            if (!context.Database.Exists())
            {
                context.Database.Create();
                Seed(context);
                context.SaveChanges();
            }
        }

        private void Seed(Context context)
        {
            throw new NotImplementedException();
        }
    }

这个不应该检查兼容性,如果数据库缺失,则会创建它。

更新:“Context”应该是您的DbContext实现类型


谢谢,Mikael。你的解决方案似乎有效。你确定默认的CreateDatabaseIfNotExists除了if (!context.Database.Exists()) { context.Database.Create(); Seed(context); }什么都不做吗? - Kristof Claes
我不确定,但在没有数据库的情况下,他们至少根据Sql Profiler生成完全相同的SQL。 - Mikael Eliasson
我刚刚反编译了EntityFramework.dll以查看它的功能。请查看此代码片段:https://gist.github.com/3017384 在调用Seed(context)之后,最重要的缺失部分是context.SaveChanges();。感谢您指引我正确的方向! - Kristof Claes
啊,我明白了。我可能会把SaveChanges放在Seed方法中,但这样做更好,因为如果他们改变了默认行为并且您想要切换回继承,它是兼容的。 - Mikael Eliasson
@MikaelEliasson 哦,那就说得通了。谢谢。我们永远不会使用此初始化程序的创建DB部分,因此我们只使用DbContext,并且似乎可以抑制对__MigrationHistory的查询。 - Jeremy Wiebe
显示剩余2条评论

0

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