2

次のようなクエリがあります。

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
                 };

これは正常にコンパイルされますが、クエリからorderItemQuantitiesandactivityQuantitiesの部分が失われるため、注文/アイテム/製品に対して単一の選択/結合/結合を取得し、エントリごとに 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

私は何万行も持っているので、これは途方もない数のクエリになります。

select で使用される匿名型から簡単にアクセスできるように、OrderItemQuantityandのActivityQuantityエントリをOrderIteman IEnumerable(または同様の) に結合する方法はありますか?

4

3 に答える 3

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 つのクエリを取得します。

于 2012-10-15T15:01:59.060 に答える
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
                 };
于 2012-10-15T22:27:12.513 に答える
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 で動作すると確信しています。

于 2012-10-15T10:50:31.317 に答える