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或其他递归解决方案。
这里我已经完成了一列以上的分组,
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)