2010-04-01 56 views
0

我爲我的網站編寫了一個簡單的OLAP查看器。以下是這些類別(抽象示例):Linq按2鍵作爲一個分組

Employee 
{ 
     ID; 
     Name; 
     Roles[]; //What Employee can do 
} 
Order 
{ 
    Price; 
    Employee Manager; 
    Employee Executive; //Maybe wrong english. The person which perform order   
} 

員工可以同時按順序經理和執行。這意味着員工角色不固定。 我必須由員工對訂單進行分組,最後通過員工密鑰進行IGrouping。

所以.GroupBy(el => new {el.Manager,el.Executive})是不允許的。

我考慮了一些與IEqualityComparable技巧,但沒有找到解決辦法。

如果somrbody會幫助我會變得很高興,謝謝。

+0

哇,你需要清理那個之前任何人都能夠幫助你。請定義什麼值= IEnumerable,以及如何分組數據,您是否試圖按員工分組訂單(忽略經理/行政人員)? – Nix 2010-04-01 18:42:35

+0

好的,我清理了。是的,我是「試圖按員工分組訂單(忽略經理/行政人員)」。 – Evgeny 2010-04-01 18:51:08

回答

0

這裏是一個解決方案,您已實現的假設/重寫的GetHashCode和等於

 var a = (
      from o in orders 
      select new { 
       Order = o, 
       Empoyee = o.Manager 
      } 
      ); 


     var b = (
      from o in orders 
      select new { 
       Order = o, 
       Empoyee = o.Executive 
      } 
      ); 

     var final = (a.Union(b)).Distinct().GroupBy(x=>x.Empoyee.ID, x=>x.Order); 

     foreach (IGrouping<int, Order> o in final) 
     { 
      o.ToList(); 
     } 
+0

這很對勁。我認爲實體框架提供者可以將其轉換爲sql,而分組將由DB服務器執行。但是1)我的OLAP查看器在創建匿名類型方面有一些限制。因爲我對同一組對象有很多依賴關係。同樣爲了簡單起見,接口必須儘可能簡單(這種轉換增加了功能)。 2)我使用動態LINQ庫。我不想用它來測試解決方案。 所以稍後我會用我的Viewer來試試這個解決方案。非常感謝你的配合。 – Evgeny 2010-04-02 03:13:44

+0

您可能會遇到麻煩,將其推送到數據庫。讓我看看我是否可以拿出一個你想要的sql等價物。你的EF模型是什麼樣的? – Nix 2010-04-02 11:14:20

0

爲了簡化瀏覽器的架構,我做了轉換功能,這對於分析準備數據。我稍後會執行分組。這產生副作用:訂單的總數和數量發生變化,因爲我們產生了一些新的訂單。但在我的情況下,這是最好的解決方案,因爲架構。如果我遇到DB Server的麻煩,我會在此操作之前調用ToList。我認爲這種風格是由我的應用程序允許的。再次感謝你! :)

public IQueryable TransForDim(IQueryable E) 
     { 
      if (this._DimType == Измерения.Сотрудники) 
      { 
       if (E.ElementType == typeof(Заказ)) 
       { 
        var Orders = E as IQueryable<Заказ>; 
        var a = (
        from o in Orders 
        select new 
        { 
         Order = o, 
         Empoyee = o.Менеджер 
        } 
        ); 

        var b = (
         from o in Orders 
         select new 
         { 
          Order = o, 
          Empoyee = o.Исполнитель 
         } 
         ); 

        var final = (a.Union(b)).Distinct().Select(e => new Заказ() 
        { 
         Менеджер = e.Empoyee, 
         Валюта = e.Order.Валюта, 
         Выполнено = e.Order.Выполнено, 
         Дата_Выполнения = e.Order.Дата_Выполнения, 
         Дата_Поступления = e.Order.Дата_Поступления, 
         Клиент = e.Order.Клиент, 
         Отменен = e.Order.Отменен, 
         Цена = e.Order.Цена 
        }); 
        return final; 
       } 
       else 
       { 
        throw new ArgumentOutOfRangeException("Измерение не обрабатывает данные кроме заказов"); 
       } 
      } 
      else return E; 
     }