4

「テーブル」と「チキン」の2つのエンティティオブジェクトがあるとします。

今、私は「翼」オブジェクトを持っていて、その翼がテーブルと鶏肉と0..1-1の関係を持つようにしたいとしましょう。言い換えれば、null許容のtable.wingとnull許容のchicken.wingが必要です。

Entity Framework 4を使用して、wingオブジェクトにテーブルまたはチキンのいずれかに関連付けることができるという制限を設ける良い方法はありますか?

注:辞書にwingedobjectsベースクラスを含めたくありません。これは、「isone」ではなく「hasone」である必要があります。

私の考えでは、参照のコレクションを独自に制限することはできないため、Entityプロパティを次のようにラップする必要があります。

public partial class Wing:
...
  public Table Table
    {
      get { return this.Table; }
      set { 
          //make sure Chicken is null
          this.Table = value;
          }
    }
...
}

これは私をかなりハッキーでクリーンすぎないように思わせるので、ベストプラクティスではないにしても、より良いプラクティスソリューションを探していました。

編集:

明確にするために、私は現在、テーブルと翼の間に0..1-1の関係があり、鶏と翼の間に0..1-1の関係があります。したがって、table.wingを作成してから、wing.tableを確認できます。私が欲しいのは、table.wing.chickenまたはchicken.wing.tableをクエリする場合、常にnull値を持つようにすることです。ウィングは、1つのテーブルまたは1つのウィングのいずれかに関連付けられている必要があります。

現在の行動の例:

@morganppdxのコメントに応えて:

この実体図を考えると:

ここに画像の説明を入力してください

そして、Program.csでは次のようになります。

class Program
{  
 static void Main(string[] args)
    {
        Model1Container container = new Model1Container();

        Wing chickenwing = new Wing { Shape = "birdlike" };
        Chicken chicken1 = new Chicken { Breed = "Andalusian", Wing = chickenwing };
        Table table1 = new Table { Style = "Mission", Wing = chickenwing }; // Should throw exception!
        container.AddToChickens(chicken1);
        container.AddToTables(table1);
        container.SaveChanges();

        Console.Write(String.Format("Table {0}'s wing has a {1} shape...", table1.Id, table1.Wing.Shape));
        Console.Write(String.Format("Table {0} has {1} chicken wings!", table1.Id, table1.Wing.Chicken.Breed));
        Console.ReadLine(); //wait for input to give us time to read
    }
}

結果のコンソールには次のように表示されます。

Table 1's wing has a birdlike shape...Table 1 has Andalusian chicken wings!

この結果は私が避けたいものです。チキンウィングがtable1に関連付けられている場合は、例外をスローする必要があります。これは、すでにchicken1に関連付けられており、テーブルとチキンの両方に関連付けることはできないためです。

関係を誤って構築している可能性が非常に高いため、@morganpdxで指定されている例外が必要な場所で取得されません。

コードはhttps://github.com/mettadore/WingThingで入手できます。

4

2 に答える 2

1

私の提案は、Wingオブジェクトを拡張する子オブジェクトを作成し、Wingオブジェクトの代わりにそれらを使用することです。

public class ChickenWing : Wing
{
  public Table Table { get { throw new NoTablesAllowedException; }}
}

public class TableWing: Wing
{
  public Chicken Chicken { get { throw new NoChickensHereException; }}
}

投稿したコードは次のようになります。

class Program
{          
    static void Main(string[] args)           
    {               
        Model1Container container = new Model1Container();                      
        ChickenWing chickenwing = new ChickenWing { Shape = "birdlike" };
        TableWing tablewing = new TableWing { Shape = "circular" };
        Chicken chicken1 = new Chicken { Breed = "Andalusian", Wing = chickenwing };               
        Table table1 = new Table { Style = "Mission", Wing = tablewing };             
        container.AddToChickens(chicken1);               
        container.AddToTables(table1);               
        container.SaveChanges();                      

        Console.Write(String.Format("Table {0}'s wing has a {1} shape...", table1.Id, table1.Wing.Shape));               
        Console.Write(String.Format("Table {0} has {1} chicken wings!", table1.Id, table1.Wing.Chicken.Breed));               
        Console.ReadLine(); //wait for input to give us time to read           
    }       
} 

私はこれまでこのようなことはしていませんが、これでうまくいくと思います。基本的に、Wingオブジェクトは、ChickenWingオブジェクトとTableWingオブジェクトを記述するためのインターフェイスとして機能しますが、これらは目立たない目的で使用される目立たないオブジェクトです。

于 2011-05-11T20:10:11.553 に答える
0

モデルを見ると、シードと増分2が異なるIDENTITYとしてテーブルIDとウィングIDを簡単に作成できると思います。1つは偶数ID、2つ目は奇数IDのみであり、そのような場合、両方に関連するウィングはありません。

重要なのは、EFの1対1の関係は常に主キーに基づいて構築されるため、wingにはテーブルまたはチキンのいずれかのプライマリキーが必要であり、排他シーケンスを定義するときに、wingが両方のテーブルにチキンを持つことができることは決してありません。

于 2011-05-11T21:25:44.230 に答える