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

本文关键字:实体 字段 使用 to Or 运算符 Linq | 更新日期: 2023-09-27 18:28:08

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

每个订单都有一个用户ID和电子邮件地址,以及额外的邮政编码和国家/地区字段。

因此,我需要根据以下规则创建组:

如果订单在一个组中有相同的(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

从逻辑上考虑,linq中似乎没有解决这个问题的优雅方案,可能需要使用SQL和CTE或其他递归解决方案。

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

这里我已经完成了一列以上的分组,

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

如果必须决定分组数据的优先级,&您不想分组的数据将作为列表。

试试这个:-

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

这是完整的工作指南。

假设您的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)