3

最初にEntityFramework4.3コードを使用しています。クラスAの2つのプロパティとクラスBのコレクションの間に2つの「1対多」の関係を作成するにはどうすればよいですか?

私のモデル:

public class Shaft
{
    public int Id { get; set; }

    public virtual Coupling FirstEnd { get; set; }
    public virtual Coupling SecondEnd { get; set; }
}

public class Coupling
{
    public int Id { get; set; }

    public virtual ICollection<Shaft> Shafts { get; set; }
}
4

1 に答える 1

2

1対多の関係は、関係の最初の端に1つの要素があり、もう一方の端に多くの要素があるため、1対多と呼ばれます。また、 0または1対多の関係を持つこともできます。これは、非多側の要素がnull(またはNULLデータベース内で)存在できることを意味するだけです。

定義しようとしているのは、2対多(またはおそらく0または1または2対多)の関係です。そのようなものは、リレーショナルデータベースには存在せず、EntityFrameworkにも存在しません。

EFとの関係を定義するときは、ソースクラスとターゲットクラスに2つのナビゲーションプロパティのペアが常に必要です。ナビゲーションプロパティの1つを省略すること可能ですが、それは、この関係の終わりを、すでに別の関係に属している別のナビゲーションプロパティに移動できることを意味するものではありません。

特定のケースでは、2つのナビゲーションプロパティFirstEndSecondEndShaft2つの異なる外部キーを表すため、2つの関係があります。したがって、に2つのコレクションが必要であるCouplingか、既存のプロパティCoupling.Shaftsをどちらか一方にFirstEnd関連付けることができますSecondEndが、両方に関連付けることはできません。もう1つの参照は、の「非表示」で公開されていないナビゲーションコレクションを指しCouplingます。(これは、あなた自身の答えのマッピングで起こることです。EFは、最初のマッピングブロックを上書きする2番目のマッピングブロックを取得し、との間の関係を作成しSecondEnd、次に、公開されていない関係Shaftsの間の別の関係を作成します。FirstEndCoupling Shafts

2つのコレクションを使用したソリューション(私の意見ではより理にかなっています)は、次のようになります。

public class Coupling
{
    public int Id { get; set; }

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
}

そしてこのマッピング:

modelBuilder.Entity<Coupling>()
    .HasMany(x => x.ShaftsWithFirstEndHere)
    .WithOptional(x => x.FirstEnd);

modelBuilder.Entity<Coupling>()
    .HasMany(x => x.ShaftsWithSecondEndHere)
    .WithOptional(x => x.SecondEnd);

読み取り専用でマップされていないヘルパープロパティを作成して、2つのコレクションを1つのコレクションに連結できますが、この連結は、2つのナビゲーションコレクションが既に読み込まれた後にメモリ内で行われます。

public class Coupling
{
    public int Id { get; set; }

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }

    // not mapped to DB because it has only a getter = readonly
    public IEnumerable<Shaft> Shafts
    {
        get { return ShaftsWithFirstEndHere.Concat(ShaftsWithSecondEndHere); }
    }
}

このような連結を自動的に行うようなマッピングはありません。1対多の関係にあるナビゲーションコレクションプロパティは、依存テーブル(Shaft例では=)の外部キーによるクエリの結果であることに注意してください。コレクションにデータを入力するために使用される外部キー(Includeたとえば、遅延読み込みがトリガーされた場合など)は、リレーションシップマッピングによって明確に定義され、キーFirstEndまたはキーのいずれかであり、SecondEnd両方ではありません。達成しようとしているのは、2つの異なる外部キーによる2つのクエリの連結結果です。そして、それはリレーションシップマッピングでは不可能です。

于 2012-07-09T21:01:52.423 に答える