EF代码的自定义初始化策略,该策略不删除表添加列
-
24-10-2019 - |
题
最新的EF代码首先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
用户表的列?
解决方案
我认为这是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团队目前正在解决此问题,但在代码首次删除时尚未准备好发布。您可以在此处查看预览: 代码第一迁移
不隶属于 StackOverflow