davin

Just a little thinking and interest!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

    接着早晨的写下去,为什么entityClientCommand和ExtensionCommand返回的结果的entity state不一样,原因是这行代码:var result = cmd.Materialize<OrderDetails>().Bind(context);的Bind()方法,在EF Extension 中的Bind()可以将entity加入到state manager.

  EF Extension中有的确许多令人兴奋的地方,为了解决最初的话题解决sp 返回Multiple result set的问题,我对NorthwindEF模型中的Order和OrderDtails实体进行扩展:

   首先添加对EF Extension .dll的引用,添加命名空间using Microsoft.Data.Extensions;由于EDM.Designer.cs是一个partial类,对一个分部(partial)类进行扩展是件容易的事,

1namespace NorthWind
2{
3    public partial class NorthwindEFEntities : ObjectContext
4    {  }
5}

  只需要在上面的类中添加扩展方法即可,下面是实现Entity Set<T>,Materializer<T>的代码,

 1 EntitySet
34
35        Materializer

  至于为什么重新实现Materializer,而不是像ExtensionCommand中那样直接调用,只要的原因是我想使用EntitySet<T>,另外重新实现Materializer可以对sp的返回结果进行处理。通过 Materializer<KeyValuePair<Orders, OrderDetails>>将Mutilple result set中的内容分割为相对应的entity,这里顺便说一下我定义的存储过程getOrderAndOrderDetails是这样的:

select a.OrderID,a.OrderDate,a.ShippedDate,a.ShipName,b.UnitPrice,b.Quantity,b.Discount
from Orders as a left join OrderDetails as b
on a.OrderID=b.OrderID
where a.OrderID=@OrderID

    下面就是对Order,OrderDetails的包装的3个方法:

 1   public Orders GetOrder(int OrderID)
 2        {
 3            DbCommand cmd = this.CreateStoreCommand("GetOrder", CommandType.StoredProcedure, new SqlParameter("@OrderID", OrderID));//specify DBCcommand
 4            Orders order = s_orderMaterializer.Materialize(cmd).SingleOrDefault();// return a most single match for this store proceduce
 5            return this.OrderSet.FindOrAttach(order);// //method made order be a tracked entity too
 6        }

 7        public OrderDetails GetOrderDetail(int OrderID)
 8        {
 9            DbCommand cmd = this.CreateStoreCommand("GetOrderDetails", CommandType.StoredProcedure, new SqlParameter("@OrderID", OrderID));
10            OrderDetails orderDetails = s_orderDetailMaterializer.Materialize(cmd).FirstOrDefault<OrderDetails>();
11            // return this.OrderDetailSet.FindOrAttach(details);
12            return orderDetails;
13        }

14        /// <summary>
15        ///return Multiple result sets
16        /// </summary>
17        /// <param name="pid">Product id</param>
18        /// <returns>Product</returns>

19        public Orders GetOrderAndOrderDetails(int OrderID)
20        {
21            DbCommand command = this.CreateStoreCommand("getOrderAndOrderDetails", CommandType.StoredProcedure, new SqlParameter("@OrderID", OrderID));
22            //this store proceduce return Multiple result sets,contain Order and OrderDetails
23            Orders order = null;
24            var orderAndDetailSet = s_OrderAndOrderDetailsMaterializer.Materialize(command);
25            foreach (var orderAndDetail in orderAndDetailSet)
26            {
27                order = this.OrderSet.FindOrAttach(orderAndDetail.Key);
28                if (null != order)
29                {
30                    order.OrderDetails.Add(orderAndDetail.Value);
31                    // order.OrderDetails = this.OrderDetailSet.FindOrAttach(orderAndDetail.Value);
32                }

33
34            }

35            return order;
36        }

   我用下面的代码来来测试上面的方法

 1Orders order = context.GetOrder(10248);//a single entity order
 2            Console.WriteLine("GetOrder:{0},OrderDetails Count:{2},Entity State:{1}", order.OrderID, order.OrderDetails.Count, order.EntityState);
 3            //writer.WriteLine(order);
 4            //DisplayResults<Orders>(order);
 5            OrderDetails orderDetails = context.GetOrderDetail(10248);//a silgle entity orderdetail
 6            //writer.WriteLine(orderDetails);
 7            Console.WriteLine("GetOrderDetail:{0},Entity State:{1}", orderDetails.OrderID, orderDetails.EntityState);
 8            Orders orderAndDetails = context.GetOrderAndOrderDetails(10248);//entity order with orderdetail
 9            Console.WriteLine("GetOrderAndOrderDetails:{0},OrderDetails Count:{1},Entity State:{2}", orderAndDetails.OrderID, orderAndDetails.OrderDetails.Count, orderAndDetails.EntityState);
10

运行的结果是:

 

 GetOrder()方法返回的order对象由于没有attach相应的OrderDetails对象,因此 order.OrderDetails.Count 为0,而GetOrderAndOrderDetails()就不同,我们将getOrderAndOrderDetails返回的Mutilple result set中的内容进行分割为Order,OrderDetails,并将OrderDetails 对象添加到Orders,这样的效果等同于

contex.Orders.Include("OrderDetails").Where(q=>q.OrderID=10248).FirstOrDefault();至于为什么GetOrderDetail返回的结果Entity State为Detach,那是因为 我将这行代码this.OrderDetailSet.FindOrAttach(details)注释了.

   EF Extension真的让我太高兴了,可以说让我感受到了sp在EF用应用不再那么局限性。可能后面我还会写一些关于还有一些关于通过设计器的映射sp的随笔.最后说一下还是说一下哪儿可以找到EF Extension.

posted on 2008-12-21 22:35  davin  阅读(2105)  评论(0)    收藏  举报