我正在处理一个实体框架代码优先项目,该项目具有相当复杂的数据模型,可以在SQL Server 2008上部署。
但是,在为某些本地端到端测试创建 SQL Server CE 数据库时,EF 创建数据库时收到以下错误消息:
System.Data.SqlServerCe.SqlCeException: The referential relationship will result in a cyclical reference that is not allowed. [ Constraint name = FK_Sites_Persons_PersonId ].
我已经在我的 DataContext 模型创建方法中禁用了ManyToManyCascadeDeleteConvention
,因此这不是问题的原因。我遇到的麻烦是有问题的关系在SQL Server 2008数据库中看起来很好 - 从我能知道的来看,它似乎是一个正常的外键,我看不到任何向另一个方向流回的东西,尽管并非不可能有一个更长路径的循环引用。我不知道为什么CE会失败,而2008年会成功。
事实证明,问题非常简单地解决了 - 尽管我已经禁用了ManyToManyCascadeDeleteConvention
但我还需要禁用OneToManyCascadeDeleteConvention
以避免循环引用问题。
您还可以考虑显式定义级联更新和删除,而不是全局禁用它们。假设一个模型:
namespace Models
{
public class Parent
{
public Parent() { this.Children = new HashSet<Child>(); }
public int id { get; set; }
public string description { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
public int id { get; set; }
public string description { get; set; }
public Parent Parent { get; set; }
}
}
在您的上下文中重写 OnModelCreate,并使用流畅的 API 为给定关系指定级联选项。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>().HasMany<Child>(p => p.Children).WithRequired(c => c.Parent).WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
当然,这是一个简单的例子,但您可以将相同的原则应用于下层实体,并专门排除导致循环引用的级联删除。