zoukankan      html  css  js  c++  java
  • 转载:Entity Framework:EDM中多对多关系(ManytoMany Acssociation)以及有效负载(Payloads)问题

    转自:http://www.cnblogs.com/subway-2008/archive/2008/08/20/1272375.html

    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测试一下   


     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中

      

                                                     图2

       但是在testMethod2中  


     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, 10100);
    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设为空,或设默认值.否则会有如下错误.

         但是那样的话就无法访问到OrderLines表中 Quantity 和PercentDiscount了.不过在Alex James的blog 上看到关于AEF开发小组在设计AEF时 


    1About Meta-Me
    2Hi,
    3my 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 


    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: 


    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 

    AssociationSet

    5从ssdl 到csdl的映射:

    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中使用这些查询 


    1var 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 .

      

  • 相关阅读:
    csuOJ啊 1553
    Codeforces 111B【看看自己和别人在代码能力上的差距!】
    hdu1849
    hdu 1847
    校队训练赛,同时也是HDU4497(数论:素数分解+组合数学)
    POJ 2356 (抽屉原理)
    线段树总结一【转】
    训练赛(1---5)D
    训练赛(1---5)A
    HDU1556 【树状数组】(改段求点)
  • 原文地址:https://www.cnblogs.com/yangfan/p/1664156.html
Copyright © 2011-2022 走看看