我正在将旧数据库迁移到一个新数据库,我们需要主要通过实体框架代码优先访问和“管理”(听起来可能有些矛盾)。
我们正在使用 MS SQL Server 2014。
旧数据库包含一些带有计算列的表。典型的 GUID 和 DateTime 的东西。
从技术上讲,这些列没有计算列规范,而是在给定默认值时使用
NEWID()
andGETDATE()
我们都知道,配置处理这些属性非常容易,DbContext
如下所示:
modelBuilder.Entity<Foo>()
.Property(t => t.Guid)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
modelBuilder.Entity<Bar>()
.Property(t => t.DTS)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
INSERTs
以上将指示实体框架在和期间忽略为此类属性提交任何提供的值UPDATEs
。
但是现在我们需要允许导入遗留记录并维护旧值,包括标记为的PRIMARY KEY
IDENTITY
这意味着我们必须在插入这些记录时设置
Id
,Guid
和DTS
属性。DatabaseGeneratedOption.None
对于 的情况
Id
,我们必须以某种方式SET IDENTITY_INSERT ... ON/OFF
在连接会话中执行。我们也想通过 Code-First 来完成这个导入过程。
如果我修改模型并“临时”并将这些属性设置为
DatabaseGeneratedOption.None
在创建数据库之后,我们将得到典型的:自创建数据库以来,支持上下文的模型已更改。考虑使用 Code First 迁移来更新数据库。
我知道我们可以生成一个空的编码迁移,
-IgnoreChanges
以便“建立”这个最新版本的上下文,但这不是一个可接受的策略,因为我们必须来回运行空迁移这个目的。
半个答案:
我们考虑过赋予这些属性可以为空的类型,即
public class Foo
{
...
public Guid? Guid { get; set; }
}
public class Bar
{
...
public DateTime? DTS { get; set; }
}
在关注初始值的默认值时DbMigration
:
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Int(nullable: false, identity: true),
Guid = c.Guid(nullable: false, defaultValueSql: "NEWID()"),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Bars",
c => new
{
Id = c.Int(nullable: false, identity: true),
DTS = c.Guid(nullable: false, defaultValueSql: "GETDATE()"),
})
.PrimaryKey(t => t.Id);
问题:
DatabaseGeneratedOption.Identity
但问题仍然存在:有没有办法在运行时DatabaseGeneratedOption.Computed
和运行时之间切换DatabaseGeneratedOption.None
?
至少,我们如何DatabaseGeneratedOption.Identity
在运行时打开/关闭?