4

私は次のクラス定義を持っています

public abstract class AbstractClass
{

    [Key]
    public string Name { get; set; }
    public virtual IndependentClass IndependentClass { get; set; }

    public string IndependentClassName { get { return IndependentClass == null ? "<NULL>" : IndependentClass.Name; } }
}

public class Impl1 : AbstractClass
{
}

public class Impl2 : AbstractClass
{
}

public class IndependentClass
{
    [Key]
    public string Name { get; set; }

    public virtual Impl1 Impl1 { get; set; }
    public virtual ICollection<Impl2> Impl2s { get; set; }
}

私のこれらでContext.OnModelCreating

modelBuilder.Entity<AbstractClass>().HasOptional(abs => abs.IndependentClass);
modelBuilder.Entity<IndependentClass>().HasRequired(ind => ind.Impl1);
modelBuilder.Entity<IndependentClass>().HasMany(ind => ind.Impl2s);

私の初期化は次のようになります(配列をコンテキストに追加してcontext.SaveChanges()トリミングします)

var impl1s = new[]
{
    new Impl1() { Name = "a" },
    new Impl1() { Name = "b" },
    new Impl1() { Name = "c" }
}

var inds = new[]
{
    new IndependentClass() { Name = "A", Impl1 = impl1s[0] },
    new IndependentClass() { Name = "B", Impl1 = impl1s[1] }
}

var impl2s = new[]
{
    new Impl2() { Name = "a1", IndependentClass = inds[0] },
    new Impl2() { Name = "a2", IndependentClass = inds[0] },
    new Impl2() { Name = "b1", IndependentClass = inds[1] },
    new Impl2() { Name = "b2", IndependentClass = inds[1] },
    new Impl2() { Name = "c1", IndependentClass = null }
}

そして最後に、各dbコレクションをダンプする単純なビューがあります。私の問題は、ナビゲーションプロパティが必要なように入力されていないことです。つまり、私のビューの出力は次のとおりです。

Independent Classes:

    A: Impl1 = a, Impl2s = []
    B: Impl1 = b, Impl2s = []

Impl1s

    a: IndependentClass = <NULL>
    b: IndependentClass = <NULL>
    c: IndependentClass = <NULL>

Impl2s

    a1: IndependentClass = A
    a2: IndependentClass = A
    b1: IndependentClass = B
    b2: IndependentClass = B
    c1: IndependentClass = <NULL>

IndepdendentClassesにはImpl2が設定されている必要があり、最初の2つのImpl1にはIndependentClassesが入力されている必要があります。

誰かが私が間違っていることを教えてもらえますか?

4

3 に答える 3

2

どうやら解決策は置き換えることです

modelBuilder.Entity<AbstractClass>().HasOptional(abs => abs.IndependentClass);
modelBuilder.Entity<IndependentClass>().HasRequired(ind => ind.Impl1);
modelBuilder.Entity<IndependentClass>().HasMany(ind => ind.Impl2s);

modelBuilder.Entity<Impl1>()
    .HasOptional(abs => abs.IndependentClass)
    .WithRequired(ind => ind.Impl1);

しかし、なぜImpl2のために何も変更する必要がないのかわかりません。

于 2012-07-22T18:38:58.933 に答える
2

モデルには、次のナビゲーションプロパティとの3つの関係があります。

  • AbstractClass.IndependentClass<->IndependentClass.(NoNavigationProperty)
  • IndependentClass.Impl1<->Impl1.(NoNavigationProperty)
  • IndependentClass.Impl2s<->Impl2.(NoNavigationProperty)

関係ごとに、関連付けの一方の端はナビゲーションプロパティとして公開されません。このモデルでは、次のことは期待されていません...

IndepdendentClassesにはImpl2が設定されている必要があり、最初の2つのImpl1にはIndependentClassesが入力されている必要があります

...IndependentClass.Impl2s初期化コードを入力したり、入力したりしないためですImpl1.IndependentClass。入力しますImpl2.IndependentClassが、このナビゲーションプロパティは別の関係に属しているため、まったく影響しませんIndependentClass.Impl2s

実際に2つの関係が必要な場合...

  • IndependentClass.Impl1<-> Impl1.IndependentClass (1対1)
  • IndependentClass.Impl2s<-> Impl2.IndependentClass(1対多)

AbstractClass...モデル内で独自のテーブルを持つエンティティである限り、これを実現することはできません。これは、宣言さImpl1.IndependentClassているタイプのナビゲーションプロパティと、Impl2.IndependentClass継承されているプロパティImpl1との間でマッピングする必要があるためです。 Impl2

エンティティを作成しない場合、つまり、マッピングコードでこの抽象クラスを使用せず、コンテキストクラスにAbstractClassを持たない場合は、上記の2つの関係が可能です。DbSet<AbstractClass>EFの場合、モデルには継承がありません。代わりに、モデルはImpl1(および)を、ベースのない1つのクラスであるImpl2のように、独自のプロパティとベースクラスのプロパティを含むエンティティと見なします。

これが、独自の回答のマッピングが期待どおりに機能する理由です。FluentAPIとの間IndependentClass.Impl1Impl1.IndependentClass明示的に1対1の関係を定義しました。との間の2番目の関係はIndependentClass.Impl2sImpl2.IndependentClass規則に1対多の関係として名前を付けることによって自動的に検出されます。

于 2012-07-22T20:52:44.510 に答える
0

コンストラクターでプロパティを初期化する必要があります。

EFは、インスタンスがEFDataContextからのものである場合にのみそれを行います。

あなたが書くときnew Impl2()、EFはまったく関与していません。

于 2012-07-22T17:29:17.027 に答える