SQL Server CE identifies a cyclical reference with Entity Framework Code First but SQL Server 2008 does not
-
05-07-2021 - |
문제
I am working on an Entity Framework Code First project that has a fairly complex Data Model which deploys absolutely fine on SQL Server 2008.
However when creating an SQL Server CE database for some local End-To-End testing I get the following error message when EF creates the database:
System.Data.SqlServerCe.SqlCeException: The referential relationship will result in a cyclical reference that is not allowed. [ Constraint name = FK_Sites_Persons_PersonId ].
I have disabled the ManyToManyCascadeDeleteConvention
in my DataContext model creation method, so that isn't the cause of the problem. The trouble I have is that the relationship in question looks fine in the SQL Server 2008 database- it appears to be a normal foreign key from what I can tell and I can't see anything flowing back in the other direction, although it is not impossible that there is a longer-path circular reference. I don't know why CE would fail and 2008 would succeed.
해결책
It turns out the problem was very simply solved- although I had disabled ManyToManyCascadeDeleteConvention
I also needed to disable the OneToManyCascadeDeleteConvention
to avoid the circular reference problem.
다른 팁
You might also consider explicitly defining the cascading updates and deletes rather than disabling them globally. Assume a model:
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; }
}
}
Override the OnModelCreating in your context and use the fluent api to specify the cascade options for a given relationship.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>().HasMany<Child>(p => p.Children).WithRequired(c => c.Parent).WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
Of course this is a simple example, but you can apply the same principle to your down-level entities and specifically exclude the cascaded delete that causes the circular reference.