5

最新的 EF Code First NuGet 包带有一个IDatabaseInitializer名为DontDropDbJustCreateTablesIfModelChanged. 顾名思义,当检测到模型更改时,它不会删除并重新创建整个数据库,只是删除并重新创建表。

假设我有这个模型类:

public class User
{
    public string Username { get; set; }

    // This property is new; the model has changed!
    public string OpenID { get; set; }
}

一个人将如何去实现一个IDatabaseInitializer不会删除任何表的方法。在这种情况下,它只会OpenID在 User 表中添加一列?

4

2 回答 2

5

我认为这是 SQL 的问题。因此,对于 SQL Server,您可以编写如下内容:

public class MyInitializer : IDatabaseInitializer<MyContext>
{
    public void InitializeDatabase(MyContext context)
    {
        context.Database.SqlCommand(
            @"
            IF NOT EXISTS (SELECT 1 FROM sys.columns AS col
                           INNER JOIN sys.tables AS tab ON tab.object_Id = col.object_Id
                           WHERE tab.Name = 'User' AND col.Name = 'OpenId')
            BEGIN
                ALTER TABLE dbo.User ADD OpenId INT; 
            END");
    }
}

但以同样的方式,您可以执行此类脚本而无需将其添加到您的应用程序中,我认为这是更好的方法。

于 2011-03-15T21:58:47.617 回答
2

使用当前版本的 Code First,您不能简单地修改架构并保留表中可能拥有的任何数据。如果在此版本中维护数据(例如参考数据/查找表)很重要,您可以创建自己的 Initializer 并覆盖 Seed 方法来填充您的表

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
    protected override void Seed(MyContext context)
    {
        var countries = new List<Country>
        {
            new Country {Id=1, Name="United Kingdom"},
            new Country{Id=2, Name="Ireland"}
        };

        countries.ForEach(c => context.Countries.Add(c));
    }
}

然后在您的 Application_Start 中使用它:

Database.SetInitializer<MyContext>(new MyDbInitializer());

我相信 EF 团队目前正在解决这个问题,但在 Code First 发布时还没有准备好发布。您可以在此处查看预览:代码优先迁移

于 2011-06-09T09:40:05.030 回答