我的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
但是。如果我评论
Items = new List<OrderItem>(GetOrderItems(p.ID))
完美结果(image2 full size)
为什么一个人加入工作呢?
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]}
表格图
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
};
}
答案 0 :(得分:1)
Items = new List...
这将导致您查询的项目的枚举,强制为每个创建的列表(以及复制的元素)调用数据库。
您可以推迟枚举和对消费者的调用,让他们将项目转换为列表,或者您可以创建一个方法,根据需要为他们创建列表或通过使您的定义更改他们的交互方式IEnumerable
并返回IQueryable
。
真正的问题是,每个项目都需要是一个列表并在主要查询中完全填充,还是可以延迟执行直到数据被执行?