我的查询看起来像这样:
var orderLines = from Order order in _orders
join OrderItem orderItem in dbc.OrderItems
on order.OrderId equals orderItem.OrderId
join Product product in dbc.Products
on orderItem.ProductId equals product.ProductId
join OrderItemQuantity oiq in dbc.OrderItemQuantities
on orderItem.OrderItemId equals oiq.OrderItemId
into orderItemQuantities
join ActivityQuantity aq in dbc.ActivityQuantities
on orderItem.OrderItemId equals aq.OrderItemId
into activityQuantities
orderby
order.OrderId ascending,
orderItem.OrderLineNumber ascending
select new {
Order = order,
Item = orderItem,
Product = product,
// I'd like to get these child items as IEnumerables or similar
ItemQuantities = orderItemQuantities,
ActivityQuantities = activityQuantities
};
此编译很好,但导致查询中缺少orderItemQuantities
和activityQuantities
部分,因此我获得了订单/商品/产品的单个选择/加入/加入,以及单独选择每个条目的OIQ / AQ:
SELECT (...) FROM [ORDERS] AS t0
INNER JOIN [ORDER_ITEMS] AS t1 ON t0.ORDER_ID = t1.ORDER_ID
INNER JOIN [PRODUCTS] AS t2 ON t1.PRODUCT_ID = t2.PRODUCT_ID
ORDER BY (...)
然后,对于每个行,它执行以下查询:
SELECT (...) FROM [ACTIVITY_QUANTITY] as t0
WHERE t0.ORDER_ITEM_ID = @p0
SELECT (...) FROM [ORDER_ITEM_QUANTITY] as t0
WHERE t0.ORDER_ITEM_ID = @p0
由于我有成千上万的行,这导致了大量的查询。
有没有办法将OrderItemQuantity
的{{1}}和ActivityQuantity
条目合并为OrderItem
(或类似的),方式可以让它们从select中使用的匿名类型?
答案 0 :(得分:0)
不知道这是否适用于LINQ to SQL,但您可以尝试
select new {
Order = order,
Item = orderItem,
Product = product,
// I'd like to get these child items as IEnumerables or similar
ItemQuantities = orderItemQuantities.ToList(),
ActivityQuantities = activityQuantities.ToList()
};
我相当确定它可以在Entity Framework中使用。
答案 1 :(得分:0)
我设法自己解决这个问题。它并不完全符合内存,但它确实有效:
// build a base query that only selects the order, item and product entities
var orderLinesBase = from Order order in _orders
join OrderItem orderItem in dbc.OrderItems
on order.OrderId equals orderItem.OrderId
join Product product in dbc.Products
on orderItem.ProductId equals product.ProductId
orderby
order.OrderId ascending,
orderItem.OrderLineNumber ascending
select new {
Order = order,
Item = orderItem,
Product = product
};
// get all OrderItemQuantity entities that are applicable to the orderLinesBase query
var orderItemQuantities = (from Order in _orders
join OrderItem orderItem in dbc.OrderItems
on order.OrderId equals orderItem.OrderId
join OrderItemQuantity oiq in dbc.OrderItemQuantities
on orderItem.OrderItemId equals oiq.OrderItemId
select oiq).ToArray();
// get all ActivityQuantity entities that are applicable to the orderLinesBase query
var activityQuantities = (from Order in _orders
join OrderItem orderItem in dbc.OrderItems
on order.OrderId equals orderItem.OrderId
join ActivityQuantity aq in dbc.ActivityQuantities
on orderItem.OrderItemId equals aq.OrderItemId
select aq).ToArray();
// notice that the above two queries use ToArray to force evaluation of the expression.
// this is just some cast by example trickery, to help with anonymous types
// it's just this method: List<T> CastListByExample<T>(T t) { return new List<T>(); }
var orderLines = Helpers.CastListByExample(new {
Order = (Order)null,
Item = (OrderItem)null,
Product = (Product)null,
ItemQuantities = (IEnumerable<OrderItemQuantity>)null,
ActivityQuantities = (IEnumberable<ActivityQuantity>)null });
// manually fill the list
foreach (var orderLine in orderLinesBase)
orderLines.Add(new
{
Order = orderLine.Order,
Item = orderLine.Item,
Product = orderLine.Product,
// use a method to filter the quantity data sets manually, because
// LINQ won't work with memory-backed enumerables
ItemQuantities = FilterByOrderItemId(orderItemQuantities, orderLine.Item.OrderItemId),
ActivityQuantities = FilterByOrderItemId(activityQuantities, orderLine.Item.OrderItemId)
});
在某些地方并不完全简洁,非常黑客,但它确实起到了作用。我总共得到6个查询,而不是数千个查询。
答案 2 :(得分:0)
尝试在内部联接之前执行组连接。这样您就可以为每个orderItem
而不是每个内连接结果执行组连接:
var orderLines = from OrderItem orderItem in dbc.OrderItems
join OrderItemQuantity oiq in dbc.OrderItemQuantities
on orderItem.OrderItemId equals oiq.OrderItemId
into orderItemQuantities
join ActivityQuantity aq in dbc.ActivityQuantities
on orderItem.OrderItemId equals aq.OrderItemId
into activityQuantities
join Order order in _orders
on orderItem.OrderId equals order.OrderId
join Product product in dbc.Products
on orderItem.ProductId equals product.ProductId
orderby
order.OrderId ascending,
orderItem.OrderLineNumber ascending
select new {
Order = order,
Item = orderItem,
Product = product,
// I'd like to get these child items as IEnumerables or similar
ItemQuantities = orderItemQuantities,
ActivityQuantities = activityQuantities
};