2017-06-13 9 views
0

Entity Frameworkに1対1の関係を作成する方法はありますか?私は1から0までの関係を示しているたくさんの例を見てきましたが、与えられた例で少なくとも1つのBarがある場合にのみFooが存在することを確信したいと思います。EF 1〜1 .. *関係

class Foo 
{ 
    List<Bar> Bars { get; set; } 
} 

class Bar 
{ 
    public Foo Foo { get; set; } 
} 

は、私はFooのテーブルではなく、バーのテーブルでNOT NULLの種類をしたいので、これは簡単にSQLによって達成されていないことがわかりますが、Entity Frameworkのは、これを扱うことができますか?

私は間違った質問をしました。なぜなら、実際には0..1から1. ..の関係を探していたからです。 Thisは私が質問するつもりの質問です。

答えて

0

私が知っているすべてのSQLデータベースで真の1対1の関係を持つことは不可能です。セット理論は1対1を可能にするが、実際にはこれを実現することは困難である。

これは基本的に鶏と卵の状況です。あなたはBarを持っていないのでFooを作成することはできず、まだFooがないのでBarを作成することはできません。基本的に1対1を作成するために必要な制約は、実際の行を挿入できないようにします。

ここで、制約を無効にしてデータを挿入してから再度有効にすることができますが、最初は制約があるという目的を本当に打ち負かしてしまうハッキーなクルーです。

したがって、1から0 .. *を受け入れて移動してください。

0

このようなソリューションを実装することの難しさと可能性については、以下の例で説明します。


マッピング一対一

マッピング一対一は(両側が必要とされる場合)にも難しいものです。

これを外部キーでどのように表現できるか想像してみましょう。再びCarIdPeopleにはCarIdCarPersonIdPersonIdPeopleを参照してください。

ここで、車のレコードを挿入するとどうなりますか?これが成功するためには、このカーレコードにはPersonIdが指定されている必要があります。このPersonIdを有効にするには、Peopleに対応するレコードが存在する必要があります。それでは、人物のレコードを挿入してみましょう。しかし、これが成功するには、有効なCarIdが人物レコード—に入っていなければなりませんが、その車はまだ挿入されていません!参照された人物のレコードを最初に挿入する必要があるため、できません。しかし、参照された人物レコードは、車のレコードを参照するため挿入することはできません。最初に挿入する必要があります(外部キー - ception :))。

これは「論理的な」方法でも表現できません。ここでも、外部キーのいずれかを削除する必要があります。あなたが落とすのはあなた次第です。外部キーが残されている側を「従属」と呼び、外部キーなしで残っている側を「プリンシパル」と呼びます。また、依存関係の一意性を保証するために、PKはFKでなければなりません。したがって、FK列を追加してモデルにインポートすることはサポートされていません。

ので、ここでの設定です:今では

public class CarEntityTypeConfiguration : EntityTypeConfiguration<Car> 
{ 
    public CarEntityTypeConfiguration() 
    { 
    this.HasRequired(c => c.Person).WithRequiredDependent(p => p.Car); 
    this.HasKey(c => c.PersonId); 
    } 
} 

あなたが本当にそれのロジックを得ている必要があります:)ただ、ちょうど依存/校長を使用するように注意してください、あなたは同様に他の側を選択することができることを覚えておいてくださいバージョンのWithRequired(あなたはまだカーでPKを設定する必要があります)。あなたがDBスキーマをチェックすると

public class PersonEntityTypeConfiguration : EntityTypeConfiguration<Person> 
{ 
    public PersonEntityTypeConfiguration() 
    { 
    this.HasRequired(p => p.Car).WithRequiredPrincipal(c => c.Person); 
    } 
} 

、あなたはそれが1対1またはゼロ溶液の場合にあったように、それはまったく同じだということを見つけることができます。もう一度、これはスキーマによって強制されるのではなく、EF自体によって実行されるからです。

class Foo 
{ 
    List<Bar> Bars { get; set; } 

    [Required] 
    public int PrimaryBarId { get; set; } 
    public Bar PrimaryBar { get; set; } 
} 

class Bar 
{ 
    public Foo Foo { get; set; } 
} 

しかし、データベースが

aFoo.PrimaryBar.FooId == aFooを強制しないことに注意してください:だからもう一度、気をつけて:)あなたが得ることができるように

0

としてクローズすることは、このようなものです。 Id

この種類のモデルは、循環FKのために更新するのが難しいです。