Linq查询问题(ado.net请求太多)

时间:2010-09-30 16:33:15

标签: c# linq

我的linq应用程序遇到了麻烦。

我有订单 OrderChangeLog OrderItems 表。在1个查询中,我想加载订单和从属表。我用Linq。

 return from p in _db.dbOrders
 select new Order
 {
 ID = p.ID, 
 OrderStatusChangelog = new List<OrderStatusChangelog>( GetOrderStatusChangelog().Where(x => x.OrderID == p.ID)),
 Items = new List<OrderItem>(GetOrderItems(p.ID)), };

在此变体中,它需要太多的ADO.NET请求(参见image1) image1 full size image1

但是。如果我评论

Items = new List<OrderItem>(GetOrderItems(p.ID))

完美结果(image2 full sizeimage2

为什么一个人加入工作呢?

P.S。我的T-SQL(由LINQ生成):

{SELECT [t0].[ID], [t0].[UserID], [t0].[DateOrder] AS [DateCreated], [t0].[ControlGUID] AS [Guid], [t0].[StatusID], [t1].[ID] AS [ID2], [t1].[OrderID], [t1].[StatusID] AS [OrderStatusID], [t1].[Comment] AS [StatusMessage], [t1].[UserID] AS [UserID2], [t1].[Date], [t2].[FullName] AS [UserName], (
SELECT COUNT(*)
FROM [dbo].[dbOrderStatusChangelog] AS [t3]
INNER JOIN [dbo].[dbUsers] AS [t4] ON [t4].[ID] = [t3].[UserID]
WHERE [t3].[OrderID] = [t0].[ID]
) AS [value], [t0].[ShippingFLP], [t0].[ShippingAddress] AS [ShippingAddressContent], [t0].[ShippingRegionID], [t0].[ShippingCity], [t0].[ShippingZIPCode], [t0].[ShippingPhone], [t0].[ShippingMetroID], [t0].[PaymentFLP], [t0].[PaymentAddress] AS [PaymentAddressContent], [t0].[PaymentRegionID], [t0].[PaymentCity], [t0].[PaymentZIPCode], [t0].[PaymentPhone], [t0].[TrackingNumber], [t0].[DateShipped], [t0].[ShippingCost] AS [Rate], [t0].[ShippingName] AS [Name], [t0].[ShippingTypeID], [t0].[PaymentName] AS [Name2], [t0].[PaymentTypeID], [t0].[SourceID], [t0].[CustomerComment], [t0].[CustomerEmail], [t0].[CustomerFLP], [t0].[DiscountAmount] AS [discountAmount], [t0].[DiscountReason] AS [discountReason], [t0].[Amount]
FROM [dbo].[dbOrders] AS [t0]
LEFT OUTER JOIN ([dbo].[dbOrderStatusChangelog] AS [t1]
    INNER JOIN [dbo].[dbUsers] AS [t2] ON [t2].[ID] = [t1].[UserID]) ON [t1].[OrderID] = [t0].[ID]
WHERE (CONVERT(Int,[t0].[StatusID])) IN (@p0, @p1, @p2)
ORDER BY [t0].[ID] DESC, [t1].[ID], [t2].[ID]}

表格图 tables

UPD1

 private IQueryable<OrderItem> GetOrderItems(int orderID)
    {
        return from p in _db.dbOrderItems
               where p.OrderID == orderID
               select new OrderItem
                          {
                              ID = p.ID,
                              ItemPrice = p.Price,
                              OrderID = p.OrderID,
                              Quantity = p.Quantity,
                              Product = new Product
                                            {
                                                ID = p.ProductID,
                                                Name = p.ProductName,
                                                Brand = new Brand { Name = p.dbProduct.dbBrand.Name }
                                            }
                          };
    }


    private IQueryable<OrderStatusChangelog> GetOrderStatusChangelog()
    {
        return from p in _db.dbOrderStatusChangelogs
               select new OrderStatusChangelog
                          {
                              Date = p.Date,
                              ID = p.ID,
                              OrderID = p.OrderID,
                              OrderStatusID = p.StatusID,
                              StatusMessage = p.Comment,
                              UserID = p.UserID,
                              UserName = p.dbUser.FullName
                          };
    }

1 个答案:

答案 0 :(得分:1)

Items = new List...

这将导致您查询的项目的枚举,强制为每个创建的列表(以及复制的元素)调用数据库。

您可以推迟枚举和对消费者的调用,让他们将项目转换为列表,或者您可以创建一个方法,根据需要为他们创建列表或通过使您的定义更改他们的交互方式IEnumerable并返回IQueryable

真正的问题是,每个项目都需要是一个列表并在主要查询中完全填充,还是可以延迟执行直到数据被执行?