私はしばらく前にこの質問をしましたが、答えはありませんでした。非常に実用的ですが、これは EF の最も奇妙な実装であると思います。ここに私の以前の投稿があります:
追加のキーワード Payload とより明確な理解で再度質問することにしました。
Apress の出版物: Entity Framework 4.0 Recipes: A Problem-Solution Approach、ページのレシピ 2-6。26 のタイトルは、ペイロードを使用した多対多の関係のモデル化です。レシピ 2-7 のタイトルは、自己参照関係のモデル化です。
それを読むと、私の問題が何であるかの基礎が得られます。違いは、私の知る限り、本や宇宙のどこにも議論されていない、ペイロードを使用した自己参照多対多があることです。
簡単に言うと、ID フィールドと Type フィールドを持つ Resource テーブルがあります。また、Parent_ID と Child_ID で構成される複合主キーと複合外部キーを持つという点で、ジャンクションまたはブリッジ テーブルとして機能する ResourceHierarchy テーブルもあります。したがって、リソース エンティティは、子リソースまたは親リソース、またはその両方として機能できます。
ここまでで、Entity Framework は Resource Entity を生成しますが、ResourceHierarchy Entity は、EDMX ファイルではエンティティではなく関係のみとして扱われるため、実際には EDMX Designer から隠されます。
生成された Resource Entity には、Resources や Resources1 などのナビゲーション プロパティがあり、それらの名前を Parents と Children に変更しました。
だから私はこのようなコードを書くことができます: (それは何もしません。いくつかの例を示しているだけです)
List<Resource> listResources = Context.Resouces.ToList()
foreach (Resource resc in listResources)
{
List<Resource> listParents = resc.Parents.ToList()
List<Resource> listChildren = resc.Children.ToList()
foreach (Resource parent in listParents)
{
Console.WriteLine(parent.Type);
}
foreach (Resource child in listChildren)
{
Console.WriteLine(child.Type);
}
resc.Children.Add(new Resource());
Console.WriteLine(resc.Parents.First().Children.First().Type);
}
他の 2 つのリソースによって共有されているリソースがあるとします。他の 2 つのリソースは、そのリソースの親になります。上記のリソースは、それぞれの親の唯一の子でもあります。はい、リソースは 3 つ以上の「親」を持つことができます。必要に応じて父親が 2 人でもかまいませんが、先祖は子供を共有しますか? 私の時計ではありません。とにかく... この時点から意味をなすためには、現実世界のシナリオからこれを考える必要があります。
開始するためのコードを次に示します。
Resource parent1 = new Resource();
Resource parent2 = new Resource();
Resource child = new Resource();
parent1.Type = "WidgetA";
parent2.Type = "WidgetB";
child.Type = "1/4 Screw"
parent1.Children.Add(child);
parent2.Children.Add(child);
Product product1 = new Product();
Product product2 = new Product();
product1.Resources.Add(parent1);
product2.Resources.Add(parent2);
したがって、ネジのある 2 つのウィジェットがあります。WidgetA と WidgetB は、Web サイトに製品としてリストされています。WidgetAが売れたらWidgetBのネジはどうなるの?これで、Resource Entity に Quantity プロパティが必要であることがわかりました。
何ヶ月も早送りして、私が現在プロジェクトに参加しており、EFがいかに制限されているかを理解した後、胎児の位置を占めています.
この部分はもう少し複雑になります。もしも
child.Quantity = 4
parent1.Quantity = 1
parent2.Quantity = 1
子の 2 つを親 1 に、子の 2 つを親 2 に割り当てることができるようにするには、どうすればそれを知ることができるでしょうか。
これは、ResourceHierarchy テーブルに「Required」と呼ばれる別の quantity(int) 列を追加することによってのみ実行できるため、次のようになります。
Parent_ID int not null,
Child_ID int not null,
Required int not null default 1
そのため、ペイロードをデータベースの ResourceHierarchy エンティティにアタッチしました。EDMX デザイナーからモデルを再生成すると、ResourceHierarchy は関係ではなくなり、エンティティになります。代わりに、EDMX デザイナーから ResourceHierarchy テーブルのみを更新することを選択した場合、ストレージ モデルに Required プロパティが表示されますが、ResourceHierarchy はリレーションシップであるため、概念モデルまたはマッピング モデルのどこにもありません。ただし、Resource テーブルと ResourceHierarchy テーブルを削除して再生成すると、ResourceHierarchy テーブルが Required 列で表示され、Entity になります。
この設定で作業することは可能ですが、単に ResourceHierarchy Relationship にアクセスして Required プロパティを取得するよりもはるかに困難です。ResourceHierarchy EntityType にストレージ モデルの Required プロパティが含まれていても、AssociationSet にアクセスした後、コードから Required プロパティにアクセスできません。ResourceHierarchy テーブルが EF のリレーションシップである場合、ストレージ モデルでは次のようになります。
<EntityType Name="ResourceHierarchy">
<Key>
<PropertyRef Name="Parent_ID" />
<PropertyRef Name="Child_ID" />
</Key>
<Property Name="Parent_ID" Type="int" Nullable="false" />
<Property Name="Child_ID" Type="int" Nullable="false" />
<Property Name="Required" Type="int" Nullable="false" />
</EntityType>
生成された EDMX ファイルをマージしようとすると、ResourceHierarchy がエンティティまたはリレーションシップのいずれかであり、両方ではないことを示すエラーが表示されます。
これは、ペイロードを使用した多対多と呼ばれます。これを自己参照階層で実装しようとすることは、EF では悪夢です。私は VS2010、SQL 2008、および .NET 4.0 Framework を使用しています。
コンセプトは、それ自体が他のリソースで構成されているか、他のリソースを構成するのに役立つリソースで構成され、それぞれが一定量のリソースを必要とする製品を持ちたいということです。これは基本的に部品表の BOM です。EF は BOM モデルをサポートしていませんか?
SQL Server 2008 の新しい HIERARCHYID 機能は、ひょっとしたら役に立ちますか?