私はこの問題を解決しようと数日を費やしました。私の問題を例証する簡単なプロジェクトを作っているうちに、私は考えられる解決策を見つけました。だから、これは二重問題のようなものです。エンティティフレームワーク、コードファーストモデリングと循環参照
しかし、最初に、少し背景情報:
私はちょうど私のASP.NET MVCプロジェクトのためのモデルを作成するために、エンティティフレームワーク4.1(EF)とコードファーストを使い始めました。 Iこれに似たいくつかのモデルが必要です。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Family
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Father> Fathers { get; set; }
public virtual ICollection<Mother> Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Father
{
public int ID { get; set; }
public string Name { get; set; }
public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Child
{
public int ID { get; set; }
public string Name { get; set; }
public int MotherID { get; set; }
public int FatherID { get; set; }
public virtual Mother Mother { get; set; }
public virtual Father Father { get; set; }
}
}
とDbContext:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace TestApp.Models
{
public class TestContext : DbContext
{
public DbSet<Family> Families { get; set; }
public DbSet<Mother> Mothers { get; set; }
public DbSet<Father> Fathers { get; set; }
public DbSet<Child> Children { get; set; }
}
}
を(ラメ例を言い訳してください、それは私の金曜日揚げ脳が思い付くことができたものです。)
家族は複数の母親と複数の父親を持つことができます。子供には母親と父親がいます。私は私の仕事で.NETの看護師の一人にチェックしました。私の仕事では、これに特別なことは何もないと同意しました。少なくとも私たちが見る限り。
しかし、私は、コードを実行したとき、私はこの例外を取得:
System.Data.SqlServerCe.SqlCeException:参照関係が許可されていない、循環参照になります。 [Constraint name = Mother_Family]
サイクルが表示されます:Family - Mother - Child - Father - Family
。しかし、私が自分でデータベーステーブルを作成した場合(私が気に入らないのは、コードファーストについて好きなことです)、私の言う限り、完全に有効なデータ構造になります。
私の最初の質問は次のとおりです。最初にコードを使用すると、これが問題になるのはなぜですか?サイクルを適切に処理する方法をEFに伝える方法はありますか?
私が最初に書いたように、私の問題を具体化するための単純なプロジェクトを作成しているうちに、私は偶然、解決策を見つけました。モデルを定義するときにいくつかのプロパティを忘れてしまっただけです。次の例では明確にするために、代わりにそれらを除去する、私は忘れてしまったモデルの部分をコメントアウトしました:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Family
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Father> Fathers { get; set; }
public virtual ICollection<Mother> Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
// public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Father
{
public int ID { get; set; }
public string Name { get; set; }
// public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Child
{
public int ID { get; set; }
public string Name { get; set; }
// public int MotherID { get; set; }
// public int FatherID { get; set; }
public virtual Mother Mother { get; set; }
public virtual Father Father { get; set; }
}
}
ので、これらSomethingID
参照プロパティを削除すると、私の問題を解決しているようです。私がこの記事の最後にリンクしているサンプルプロジェクトのコントローラで見てきたように、私はまだ周りを循環して何も問題なくmothers.First().Family.Fathers.First().Children.First().Mother.Family.Name
のようなことをすることができます。しかし、私が見てきたEFやコードファーストモデリングに関するチュートリアルや例(例:this one by Scott Guthrie)にはこれらのプロパティが含まれているため、それらを使用しないように間違っていると感じています。
したがって、私の2番目の質問は次のとおりです。私はまだこれを発見していない欠点と問題がありますか?
ここでプロジェクトの例をダウンロード:http://blackfin.cannedtuna.org/cyclical-reference-test-app.zip、TestSolution.slnを開きます。このプロパティは、サンプルプロジェクトでコメント化されています。 TestModels.csの行のコメントを外してプロパティを追加し、周期的な参照例外を発生させます。
NB:解決策は、c:\ TestAppにあるSQL CEデータベースを作成してシードすることです。
アップデート、2011年12月自衛隊: 私は技術的にこの問題を解決したことがないが、私は私の仕事をやめ、私はマイクロソフトのテクノロジを使用する必要はありません別の仕事を見つけました。この種の解決済み私の問題:
問題を修正するときに書いた古い場所での技術サポートとして: "回避策または解決策が提供されました"。
私がSFで読んだより良い質問の1つ。よくやった。あなたの「回避策」がありがとう! –