2014-10-29 40 views
2

我的订单列表,需要以有效的方式来创建相似的订单的基团(优选地没有拉回所有的订单和手动比较)LINQ到实体上的多个字段分组通过OR运算符

每个订单具有与邮编附加字段和国家

,所以我需要下列规则创建组

如果订单有相同的(用户ID 电子邮件地址)(postco用户ID和电子邮件地址德国家)代替组

鉴于以下实体和数据

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 

的只有我能途径似乎认为通过手动迭代来做到这一点n在内存中

这可能与Linq干净地对实体做?

更新

研究这一段时间之后,我想我已经得出结论,只有这样才能实现我想要的是有可能做2个groupbys和手动记忆将它们组合起来

UPDATE2

想着这在逻辑上有看似在LINQ这个问题没有很好的解决方案,并可能需要使用SQL和CTE的或其他一些递归解决方案来完成。生病标记最接近的解决方案是正确的

回答

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

+0

这是最接近的解决方案,但我认为要正确地工作,生病必须采取稍微不同的方法。谢谢 – 2014-10-30 01:13:02

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 = "[email protected]", PostCode = 111, Country = "India" }); 
      orderList.Add(new Order { UserId = 2, OrderId = 2007, Email = "[email protected]", PostCode = 111, Country = "India" }); 
      orderList.Add(new Order { UserId = 3, OrderId = 2007, Email = "[email protected]", PostCode = 111, Country = "India" }); 
      orderList.Add(new Order { UserId = 4, OrderId = 2008, Email = "[email protected]", PostCode = 111, Country = "India" }); 
      orderList.Add(new Order { UserId = 5, OrderId = 2008, Email = "[email protected]", PostCode = 111, Country = "India" }); 
      orderList.Add(new Order { UserId = 6, OrderId = 2001, Email = "[email protected]", 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) 
+0

感谢您的回复,但是,这个组由UserId或电子邮件,因为即时通讯不知道我怎么会把其他conidtions(包括OR)在集团 – 2014-10-29 04:10:01

+0

如果你想你可以另外添加。像'.GroupBy(u => u.UserId)''或者如果你想要所有的字段被分组就像这样'.GroupBy(u => u.OrderId && u.UserId && u.Email)' – RajeshKdev 2014-10-29 04:14:34

+0

@Saruman I只是再次更新我的答案。那工作? – RajeshKdev 2014-10-29 04:21:56

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

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

+0

+1是的。这可以是另一个答案。但是,结果的返回类型是什么?如果我不想在这里使用'var'。 – RajeshKdev 2014-10-29 04:26:30

+0

@RJK我编辑了我的答案,maybw这将帮助你 – Rahul 2014-10-29 04:41:30