Linq to Entities使用Or运算符对多个字段进行分组

时间:2014-10-29 03:43:05

标签: c# linq entity-framework

我有一个订单列表,需要以有效的方式创建类似订单组(最好不要撤回所有订单并手动比较)

每个订单都有一个UserId和电子邮件地址,其中包含邮政编码和国家/地区的其他字段

所以我需要按照以下规则创建群组

如果订单具有相同的(UserId 电子邮件地址)(邮政编码国家/地区),则

给出以下实体和数据

public class Order
{
        public int UserId { get; set; }
        public int OrderId { get; set; }
        public string Email { get; set; }
        public int PostCode { get; set; }
        public string Country { get; set; }
}

示例数据

OrderId UserId  Email   PostCode    Country
1       1       blah1   111         au
2       1       blah2   111         au
3       2       blah1   111         au
4       2       blah2   111         au
5       3       blah3   111         nz
6       3       blah3   111         nz

示例结果

Group 1
1       1       blah1   111         au
2       1       blah2   111         au
3       2       blah1   111         au
4       2       blah2   111         au

Group 2
5       3       blah3   111         nz
6       3       blah3   111         nz

我似乎只想通过内存中的手动迭代来实现这一目的

这可以与Linq干净利落地实现吗?

更新

经过一段时间的研究后,我想我得出的结论是,实现我想要的唯一方法就是可以做2个groupbys并手动将它们组合在内存中

UPDATE2

在逻辑上考虑这个问题似乎在linq中没有解决这个问题的优雅解决方案,可能需要使用SQL和CTE或其他一些递归解决方案。我将最接近的解决方案标记为正确

3 个答案:

答案 0 :(得分:1)

在这里,我已经在超过1列上完成了Group by,

  OrderViewModel OrderList   =from ord in order
        group ord by new
        {
            ord.PostCode,
            ord.Country,
            ord.UserID,
            ord.Email,
            ord.OrderID
        } into gr
        select new OrderViewModel
        {
            OrderID = gr.Key.OrderID,
            UserID = gr.Key.UserID,
            Email = gr.Key.Email,
            PostCode=gr.key.PostCode,
            Country=gr.key.Country,
            OrderList= gr.ToList()
        };

其中OrderViewModel是::

public class Order
{
        public int UserId { get; set; }
        public int OrderId { get; set; }
        public string Email { get; set; }
        public int PostCode { get; set; }
        public string Country { get; set; }
        public List<Order> OrderList { get; set; }
}

您应该在哪里决定分组数据的优先级, &amp;您不希望分组的数据将被视为列表。

答案 1 :(得分:0)

假设您的Order Class如下所示:

public class Order
{
        public int UserId { get; set; }
        public int OrderId { get; set; }
        public string Email { get; set; }
        public int PostCode { get; set; }
        public string Country { get; set; }
}

假设和Grouping the List of Orders如下:

public List<List<Order>> grouping()
{           
            // List of Orders to Group
            List<Order> orderList = new List<Order>();
            orderList.Add(new Order { UserId = 1, OrderId = 2007, Email = "blah1@test.com", PostCode = 111, Country = "India" });
            orderList.Add(new Order { UserId = 2, OrderId = 2007, Email = "blah1@test.com", PostCode = 111, Country = "India" });
            orderList.Add(new Order { UserId = 3, OrderId = 2007, Email = "blah1@test.com", PostCode = 111, Country = "India" });
            orderList.Add(new Order { UserId = 4, OrderId = 2008, Email = "blah1@test.com", PostCode = 111, Country = "India" });
            orderList.Add(new Order { UserId = 5, OrderId = 2008, Email = "blah1@test.com", PostCode = 111, Country = "India" });
            orderList.Add(new Order { UserId = 6, OrderId = 2001, Email = "blah1@test.com", PostCode = 111, Country = "India" });

            // Grouping
            var groupedOrderList = orderList
                .GroupBy(u => u.OrderId)
                .Select(grp => grp.ToList()).ToList();  // Groping the Records based on the OrderId 

            return groupedOrderList; // The Result will be List<List<Order>>
}

您的小组声明将group by OrderId。结果将如您所示,如上所示。

<强>更新

您还可以添加其他字段,以便根据多个字段进行分组。

如下所示:

.GroupBy(u => u.OrderId & u.UserId)

答案 2 :(得分:0)

试试这个: -

 var query = from ord in orders
                        group ord by new { ord.Country, ord.PostCode } into g
                        select new
                            {
                                Country = g.Key.Country,
                                PostCode = g.Key.PostCode,
                                Orders = g.GroupBy(x => x.OrderId)
                                          .GroupBy(i => i.Count() > 1 ?
                                              new { OrderID = i.Key, Email = default(string) }
                                              : new { OrderID = default(int), i.First().Email })
                                          .Select(o => o.Count() == 1 ?
                                               new { o.Key, Orders = o.First().ToList() }
                                               : new { o.Key, Orders = o.Select(z => z.First()).ToList() })
                            };

以下是完整的工作Fiddle