在EDM中的关系Assciation 如果是One:One or One:many 按照设计器的Wizard一步步下来,然后做TableMapping就可以了(虽然在EDM之前也接触过Nhibernate,但仅仅局限于对它的查询.mapping的概念的不是很强烈)那么对于many:many的Associationn呢,以Order <- (*-*) -> Product 这样的一个many:many来讲,我们在数据库模型里面必须要借助第三表OrderLines来实现
即Order <- (1-*) -> OrderLines<- (*-1) -> Product在EDM中Order,Product表映射为实体,而OrderLines要怎么处理?
有2中情况:
1.如果当OrderLines表只有2个字段,分别作为外键指向Order,Product,那么在EDM中只需将Association(Order -Product)关系映射到OrderLines(这里使用的表是OrderLines1只有2个字段)
图1
创建一个testProject测试一下
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
Code
1 [TestMethod]
2 public void TestMethod1()
3 {
4 using (edmEntities1 context = new edmEntities1())
5 {
6 Products p = new Products();
7 p.ID = new Random().Next(10);
8 p.Name = "joy";
9 Orders o = Orders.CreateOrders(new Random().Next(10));
10 o.Products.Add(p);
11 context.AddToOrders(o);
12 context.SaveChanges();
13 var query = from oo in context.Orders from pp in oo.Products where oo.ID == 1 select pp;
14 var query1 = context.Orders.Include("Products").Where("it.ID==1");//ESQL查询
15 var query2 = context.Orders.Include("Products").Where(q => q.ID == 1);
16 }
17 }
18
我们可以通过
var query = from oo in context.Orders from pp in oo.Products where oo.ID == 1 select pp;
var query1 = context.Orders.Include("Products").Where("it.ID==1");
var query2 = context.Orders.Include("Products").Where(q => q.ID == 1);
这样的的方式对Order ,Product进行关联查询了.
2.当OrderLines表除了存放Order Products关系外,还有其他字段,这就是所谓的有效负载(Payloads),我们只好将OrderLines也作为对象展现在
EDM中
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzkvOS83LzMvNjIvMDRmZTI3ODI5NjRkOTYwMDIyMDgyNmU5YWE4OTAyODcuanBl.jpe?w=700&webp=1)
图2
但是在testMethod2中
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
Code
1 [TestMethod]
2 public void TestMethod2()
3 {
4 using (edmEntities context = new edmEntities())
5 {
6 Products p = new Products();
7 p.ID = new Random().Next(10);
8 p.Name = "boy";
9 Orders o = Orders.CreateOrders(new Random().Next(10), 11);
10 OrderLines ol = OrderLines.CreateOrderLines(o.ID, p.ID, 10, 100);
11 o.OrderLines.Add(ol);
12 p.OrderLines.Add(ol);
13 context.AddToProducts(p);
14 context.AddToOrders(o);
15 context.SaveChanges();
16 var query = from oo in context.Orders from ool in o.OrderLines;
17 where ool.OrderID == 1 select ool;
18 IQueryable<OrderLines> query1 = context.OrderLines.Where(q => q.Products.ID == 1);
19 IQueryable<OrderLines> query2 = context.OrderLines.Where("it.Products.ID=1");
20 }
21 }
22
这样就很难从Order查询得到Product的集合,反之亦然.那么能不能也像第一种情况那样不将OrderLines映射为一个对象,当然是可以的, 但是必须将OrderLines多余的信息Quantity, PercentDiscount设为空,或设默认值.否则会有如下错误.![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMS85LzIvOTEvMjg0YmIxOGNlMThhNWFjMDRhZTU2MjRiMmRjODdmNGYuanBl.jpe?w=700&webp=1)
但是那样的话就无法访问到OrderLines表中 Quantity 和PercentDiscount了.不过在Alex James的blog 上看到关于AEF开发小组在设计AEF时
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
About Alex
1
About Meta-Me
2
Hi,
3
my name is Alex James, a Program Manager working on the ADO.NET team at Microsoft. My focus is the Entity Framework, the Entity Data Model and in particular Metadata.
对于Association(Many to many )的有效负载(Payloads)问题的考虑,准备通过暴露一个事件来访问 OrderLines(Association),不过由于实现比较复杂
被开发小组否定了,给出了另一种解决方案:创建一个ReadOnly的Association,就可以在EDM中保留OrderLines对象又可以像第一种情况一样
实现Order, Product的相互访问,进而实现从Order,Product的一个loop.
用XML浏览器打开图2的模型,
1.在ssdl内 添加一个entityType: ProductOrders
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
EntityType
1
<EntityType Name="ProductOrders">
2
<Key>
3
<PropertyRef Name="ProductID" />
4
<PropertyRef Name="OrderID" />
5
</Key>
6
<Property Name="ProductID" Type="int" Nullable="false" />
7
<Property Name="OrderID" Type="int" Nullable="false" />
8
</EntityType>
2.添加一个EntitySet
1
<EntitySet Name="ProductOrders" EntityType="edmModel.Store.ProductOrders" >
2 <DefiningQuery>
3 SELECT ProductID, OrderID FROM OrderLines
4 </DefiningQuery>
5 </EntitySet>
3.在csdl内 添加2个many to many 的Association:
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
Association
1
<Association Name="ProductOrders">
2
<End Role="Products" Type="edmModel.Products" Multiplicity="*" />
3
<End Role="Orders" Type="edmModel.Orders" Multiplicity="*" />
4
</Association>
4 添加AssociationSet:ProductOrders
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
AssociationSet
1
<AssociationSet Name="ProductOrders" Association="edmModel.ProductOrders">
2
<End Role="Products" EntitySet="Products" />
3
<End Role="Orders" EntitySet="Orders" />
4
</AssociationSet>
5从ssdl 到csdl的映射:
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
AssociationSetMapping
1
<AssociationSetMapping Name="ProductOrders" TypeName="edmModel.ProductOrders" StoreEntitySet="ProductOrders">
2
<EndProperty Name="Products">
3
<ScalarProperty Name="ID" ColumnName="ProductID"/>
4
</EndProperty>
5
<EndProperty Name="Orders">
6
<ScalarProperty Name="ID" ColumnName="OrderID"/>
7
</EndProperty>
8
</AssociationSetMapping>
然后在csdl分为Order Product添加Nagivation Property:
<NavigationProperty Name="Products" Relationship="edmModel.ProductOrders" FromRole="Orders" ToRole="Products"/>
<NavigationProperty Name="Orders" Relationship="edmModel.ProductOrders" FromRole="Products" ToRole="Orders">
做完这些保存打开设计器,看完成了一个Loop:
图3
这样就可以在testMethod2中使用这些查询
![Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题 Entity Framework:EDM中多对多关系(Many-to-Many Acssociation)以及有效负载(Payloads)问题](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzUvMC80LzYvMjgvOTMxMGU4NWExNGFmOTlkZTQ4MTFmZjRjNzdmMWY5MTEuanBl.jpe?w=700&webp=1)
query
1
var query3 = from order in context.Orders from product in order.Products where product.ID == 1 select product;
2
p = query3 as Products;
3
var query4 = context.Products.Include("Orders").Where(pp=>pp.ID==1).FirstOrDefault();
但对于以上模型,使用下面的o.Products.Add(p)是不能成功的,因为在ssdl中我们只能定义Query .