0

事実上再帰参照を必要とする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;
        }
    }

このエラーを報告して解決策を探している人々の多くのインスタンスを確認しましたが、そのすべてが答えを理解できますが、この再帰構造を持っている人はいません。

提供された支援に感謝します。

4

2 に答える 2

0

解決策は、関係の両端を明示し、次のようにマッピングを追加することでした。

    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 の初心者としての私の感覚は、既定値に依存するよりも明示的に記述した方がよいということです。

于 2013-05-17T07:31:59.083 に答える
0

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すると、それが気に入らず、関係が満たされないのです。

それがリレーションシップの動作方法ではない場合は、Fluent API をオーバーライドOnModelCreating()してDbContext、Fluent API を使用して設定方法を定義する必要がある場合があります。

于 2013-05-16T14:45:58.097 に答える