2014-10-29 19 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