不久前我问了这个问题而没有答案,我相信这可能是 EF 最奇怪的实现,尽管它非常实用。这是我以前的帖子:
我决定用额外的关键字 Payload 和更清晰的理解再次询问。
在 Apress 出版物中:Entity Framework 4.0 Recipes: A Problem-Solution Approach,第 2-6 页的配方。26 题为使用有效负载建模多对多关系。配方 2-7 的标题是为自指关系建模。
阅读这将为您提供我的问题的基础,不同之处在于我有一个带有有效负载的自我参照多对多,据我所知,这本书或宇宙中的任何地方都没有讨论过。
简单地说,我有一个包含 ID 和类型字段的资源表。我还有一个 ResourceHierarchy 表,它用作联结表或桥表,因为它有一个由 Parent_ID 和 Child_ID 组成的复合主键和一个复合外键。因此,资源实体可以用作子资源或父资源或两者兼而有之。
到目前为止,实体框架将生成资源实体,但 ResourceHierarchy 实体实际上对 EDMX 设计器是隐藏的,因为在 EDMX 文件中,它仅被视为关系而不是实体。
生成的资源实体将具有诸如 Resources 和 Resources1 之类的导航属性,我将其重命名为 Parent 和 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);
}
假设我有一个由其他两个资源共享的资源。另外两个资源将是所述资源的父母。所述资源也是其每个父母的唯一孩子。是的,一个资源可以有三个或更多“父母”,如果你愿意,甚至可以有两个父亲,但祖先会共享一个孩子吗?不在我的手表上。所以无论如何......我们必须从现实世界的场景中考虑这一点,以便从这一点开始有意义。
这是一些让我们开始的代码:
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);
所以我们有两个有螺丝的小部件。WidgetA 和 WidgetB 在网站上列为产品。如果 WidgetA 卖了,WidgetB 的螺丝钉会怎样?所以现在您看到我们需要资源实体上的 Quantity 属性。
快进好几个月了,我目前正在我的项目中,并在意识到 EF 有多么有限后假设胎儿位置。
这部分变得有点复杂。如果
child.Quantity = 4
parent1.Quantity = 1
parent2.Quantity = 1
我们如何知道或设置它,以便我们可以将孩子的 2 个分配给 parent1,将孩子的 2 个分配给 parent2?
这只能通过向 ResourceHierarchy 表添加另一个数量(int)列来完成,我们将其称为“必需”,因此它看起来像:
Parent_ID int not null,
Child_ID int not null,
Required int not null default 1
因此,我们已将有效负载附加到 db 中的 ResourceHierarchy 实体。如果我们从 EDMX 设计器重新生成模型,ResourceHierarchy 不再是关系,而是现在是实体。如果我选择仅从 EDMX 设计器刷新 ResourceHierarchy 表,我可以在存储模型中看到 Required 属性,但它不在概念模型或映射模型中的任何位置,因为 ResourceHierarchy 将是一种关系。但是,如果我删除 Resource 表和 ResourceHierarchy 表并重新生成它们,则 ResourceHierarchy 表现在在Required 列中可见并且它现在是一个实体。
可以使用此设置,但它比简单地访问 ResourceHierarchy 关系和检索所需属性要困难得多。即使 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 框架。
这个概念是我希望拥有由资源组成的产品,这些资源本身由其他资源组成或用于组成其他资源,并且每个产品都需要一定数量的资源。它基本上是物料清单 BOM。EF 不支持 BOM 模型吗?
SQL Server 2008 中的新 HIERARCHYID 功能是否会有所帮助?