最新的EF代码首先Nuget软件包带有自定义实现 IDatabaseInitializerDontDropDbJustCreateTablesIfModelChanged. 。顾名思义,当检测到模型更改时,它不会掉落并重新创建整个数据库,只需掉落并重新创建表即可。

说我有这个模型类:

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

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

如何实施 IDatabaseInitializer也不会丢下任何桌子. 。在这种情况下,它只会添加 OpenID 用户表的列?

有帮助吗?

解决方案

我认为这是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");
    }
}

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

其他提示

首先使用当前版本的代码,您不能简单地修改模式并保留表中可能拥有的任何数据。如果维护数据,例如参考数据 /查找表在此版本中很重要,则可以创建自己的初始化器并覆盖种子方法以填充表格

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团队目前正在解决此问题,但在代码首次删除时尚未准备好发布。您可以在此处查看预览: 代码第一迁移

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top