是否可以使用一个查询将LINQ集合分组为字典?

时间:2010-03-01 19:25:52

标签: asp.net-mvc linq-to-sql dictionary grouping

给出与订单表(订单)相关的订单商品表(订单商品),后者又与用户表相关联(用户),是否可以检索所有 OrderItems 并通过 OrderId 将它们分组到一个字典中,只需一个查询?即。不对 OrderItems 结果集执行迭代或对每个订单执行查询。

所需的控制器伪代码

Dictionary<int,IEnumerable<OrderItem>> OrderItems = DataContext.OrderItems.ToDictionary(Key => oi.OrderId, Value => oi.ToList());

所需用法:

IEnumerable<OrderItem> currentOrderItems = OrderItems[123]; // where 123 is OrderId

当前方法

在我的控制器中,我目前检索用户的订单和订单项以传递到订单视图:

ViewData["Orders"] = (from o in orders
                      where o.UserId equals CurrentUserId
                      orderby o.DateCreated descending)
                     .ToList();

ViewData["OrderItems"] = (from oi in DataContext.OrderItems
                        join o in DataContext.Orders
                        on oi.OrderId equals o.OrderId
                        where o.UserId equals CurrentUserId
                        select oi)
                        .ToList();

然后在我看来,我检索所有订单商品:

IEnumerable<OrderItem> orderItems = ViewData["OrderItems"] as IEnumerable<OrderItem>;

并使用LINQ对每个订单的订单项进行分组和显示:

IEnumerable<OrderItem> currentOrderItems = orderItems.Where(
                                            i => i.OrderId == order.OrderId
                                           );

这非常有效,因为只有两个查询传递给数据库,一些处理在视图中完成。但理想情况下,这应该在控制器中完成。

2 个答案:

答案 0 :(得分:1)

解决了!使用ToLookup(...)

ViewData["OrderItems"] = (from oi in DataContext.OrderItems
                          join o in DataContext.Orders
                          on oi.OrderId equals o.OrderId
                          where o.UserId == UserId
                          select oi).ToLookup(oi => oi.OrderId, oi => oi);

在我看来:

ILookup<int,OrderItem> orderItems = ViewData["OrderItems"] as ILookup<int,OrderItem>;

foreach (Order order in orders)
{
    DisplayOrder(order);

    // Now display this order's items:
    foreach(OrderItem item in orderItems[order.OrderId])
    {
        DisplayOrderItem(item);
    }
}

跟踪仅显示一个用于创建查找的查询。

看起来我养成了回答自己问题的习惯......

答案 1 :(得分:0)

我认为最好的办法是创建一个方法,接受键的lambda和要插入字典的列表,然后简单地枚举列表并使用lambda中提供的键添加到字典中。该方法可以是IDictionary的扩展方法,让我们称之为AddRangeWithKeyType()