我有一个订单列表,需要以有效的方式创建类似订单组(最好不要撤回所有订单并手动比较)
每个订单都有一个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或其他一些递归解决方案。我将最接近的解决方案标记为正确
答案 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。