我在 EF6 项目中为现有属性添加了一个外键,该属性注释为
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
VS 为其生成迁移,并将 FK 添加到 DB 中。我按预期在查询中使用了 FK。一切看起来都很好。
后来,包含该属性的实体实例的更新导致了此错误:“ReferentialConstraint 中的依赖属性被映射到存储生成的列。”。 EF6不支持这样的FK吗?我发现的一个答案建议不要,但我找不到任何说明这一点的 MS 文档。如果 EF 不支持,为什么要将 FK 添加到数据库并在查询中使用关系?
编辑 1:FK 是可选的(即可为空)。新实例始终将其设置为 null。 SP 在某些情况下运行并将其设置为指向其相关实例。我不确定它是否相关,但它是对同一个表中不同行的引用。
编辑2:下面的代码经过简化。 CloneID 和 AutoCloneID 都是自引用。 ClonedID 可以由用户在应用程序中设置。 AutoCloneID 由存储过程设置。我的更改是 a) 公共虚拟 BaseProperty 行 b) 添加到 OnModelCreating 的 3 行。
public class BaseProperty
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int? CloneID { get; set; }
public virtual BaseProperty Clone { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int? AutoCloneID { get; set; }
public virtual BaseProperty AutoClone { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseProperty>()
.HasOptional(p => p.AutoClone)
.WithMany();
}
根据我所做的更改,在应用程序中更新和保存 BaseProperty 通常没问题。在应用程序中更新 CloneID 时会发生该错误。我想强调的是,创建新 FK 的迁移是有效的,并且使用它的 EF 查询是有效的。
编辑3:如果更改CloneID后保存时将AutoCloneID设置为null,则不会出现错误。为什么?通过这一更改,我似乎有一个与错误消息相矛盾的工作 FK。
编辑 4:使用该属性的原因是从迁移中排除 AutoCloneID,这将允许应用程序干扰内部数据库存储过程分配给它的值。该应用程序使用存储过程进行 DML。如果删除该属性,则将创建迁移以生成新的插入和更新存储过程,其中将包含 AutoCloneID。
外键(子表中)的值根据建立的关系指向父表中的相应行。因此,从书中,我们可以联系到作者,从帖子中,我们可以联系到博客,等等......
如果您将此值设置为“数据库计算值”,那么每次您更新子行(Book)或插入新行时,都会从数据库引擎为FK计算一个新值...我认为这没有任何意义,因为新的 FK 值不一定指向父表中存在的行,因此会出现错误。