角色的冲突变化…在EF4
本文关键字:EF4 变化 冲突 角色 | 更新日期: 2023-09-27 18:13:59
我有一个POCO代码优先模型,它需要有效的递归引用。当我尝试创建实体时,我得到"冲突的变化到角色…"错误,如标题。
下面是一组简化的类来说明这个问题: public class Master
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Query2 Query { get; set; }
}
public class Query2
{
public Query2()
{
Columns = new List<Column2>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Column2> Columns { get; set; }
}
public class Column2
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Query2 Query { get; set; }
}
属性Column2.Query存在问题。
下面是生成自动示例数据的代码: public class TestContext : DbContext
{
public TestContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<Master> Masters { get; set; }
public DbSet<Query2> Queries { get; set; }
public DbSet<Column2> Columns { get; set; }
}
public class TestContextInitializer : DropCreateDatabaseIfModelChanges<TestContext>
{
protected override void Seed(TestContext context)
{
Master master = new Master() { Name = "Test" };
master.Query = new Query2() { Name = "Query1" };
Column2 col = new Column2() { Name = "Column1" };
master.Query.Columns.Add(col);
col.Query = new Query2() { Name = "Query2" };
col.Query.Columns.Add(new Column2() { Name = "Column2" });
context.Masters.Add(master);
}
}
这会触发错误:
private void Test2()
{
ZapDatabase(@"D:'Visual Studio'TestDPDatabase'TestDPDatabase'TestContext.sdf");
System.Data.Entity.Database.SetInitializer<TestContext>(new TestContextInitializer());
using (TestContext cont = new TestContext())
{
var result = cont.Masters.Include("Query").Include("Query.Columns").Include("Query.Columns.Query").Include("Query.Columns.Query.Columns").ToList();
int objects = result.Count;
}
}
我检查了许多报告此错误并寻求解决方案的人的实例,所有这些我都能理解答案,但没有一个具有这种递归结构。
非常感谢您提供的帮助。
我认为问题在于您在Seed()
方法中创建的实体与EF推断的关系相冲突。默认情况下,当您有像
public class Query2
{
...
public virtual ICollection<Column2> Columns { get; set; }
}
和
public class Column2
{
...
public virtual Query2 Query { get; set; }
}
…EF假设它是一个互反关系。因此,当您将col
添加到master.Query.Columns
中,而将col.Query
设置为一个新实例时,它不喜欢它——关系不满足。
如果这不是你想要的关系工作的方式,你可能不得不覆盖OnModelCreating()
在你的DbContext
和使用Fluent API来定义事情应该如何设置。
解决方案是明确关系的两端,并添加如下映射:
public class Master
{
[Key()]
public int MasterId { get; set; }
public string Name { get; set; }
public virtual Query2 Query { get; set; }
}
public class Query2
{
public Query2()
{
Columns = new List<Column2>();
}
[Key()]
public int QueryId { get; set; }
public string Name { get; set; }
public virtual Master Master { get; set; }
public virtual ICollection<Column2> Columns { get; set; }
}
public class Column2
{
[Key()]
public int ColumnId { get; set; }
public string Name { get; set; }
public virtual Query2 Query { get; set; }
public virtual Query2 ColQuery { get; set; }
}
和映射
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Query2>().HasRequired(q => q.Master).WithRequiredPrincipal(m => m.Query);
}
作为一个EF新手,我的感觉是,最好是显式的,而不是依赖默认值。