2014-10-03 50 views
1

我有,我想組和投硬型LINQ表達式List<DocumentGroup>的LINQ表達的GroupBy

這LINQ查詢工作正常:

var DocumentGroups = (from dt in DocumentTypes 
         let dg = dt.DocumentGroup 
         select new DocumentGroup(){ 
          Name = dg.Namn, 
          Id = dg.Id 
         }).GroupBy(group => group.Id).ToList(); 

現在我想要做同樣的查詢和投它以一個List<DocumentGroup>但我收到此錯誤:

Unable to cast object of type 'Grouping[System.Guid,ConsoleApplication1+DocumentGroup]' to type 'DocumentGroup'.

List<DocumentGroup> DocumentGroups = (from dt in DocumentTypes 
          let dg = dt.DocumentGroup 
          select new DocumentGroup(){ 
           Name = dg.Namn, 
           Id = dg.Id 
          }).GroupBy(group => group.Id).Cast<DocumentGroup>.ToList(); 

如果我雷莫ve .GroupBy(group => group.Id)來自linq表達式,它工作正常,但我需要組表達式進行過濾。我該如何做這項工作?

的DocumentGroup類

public class DocumentGroup 
{ 
    public string Name { get; set; } 
    public Guid Id { get; set; } 
} 
+0

如果您通過'ID'進行分組,則無法訪問聚合之外的'Name'。你想做什麼? – DavidG 2014-10-03 08:13:44

回答

4

當您使用GroupBy你組。因此將一個組投射到單個項目將會失敗。

如果你想要做的是消除重複,那麼你可以選擇從每個組中的第一項:

var DocumentGroups = (from dt in DocumentTypes 
         let dg = dt.DocumentGroup 
         select new DocumentGroup() 
          { 
           Name = dg.Namn, 
           Id = dg.Id 
          }).GroupBy(group => group.Id) 
           .Select(g => g.First()) 
           .ToList(); 
+1

太好了。現在它可以工作,我也可以訪問Name嗎? :) 你能解釋我做錯了什麼嗎? – user3046164 2014-10-03 08:17:48

+0

@ user3046164當你使用groupby你有組時,例如你得到一個'IGrouping '其中'T'是鍵的類型,'K'是你的值的類型。這是一個組,而不是一個單一的項目組中可以有多個項目,對嗎?這是分組的目的。你試圖直接將一個組施加到單個項目上,比如將一個Foos列表轉換爲單個Foo,這就是爲什麼它失敗了 – 2014-10-03 08:23:59

0

做之前GroupBy你有DocumentGroup列表(如單維數組)

1 Name1  <record 1 of DocumentGroup> 
1 Name2  <record 2 of DocumentGroup> 
1 Name3  <record 3 of DocumentGroup> 
2 Name4  <record 4 of DocumentGroup> 
3 Name5  <record 5 of DocumentGroup> 

GroupBy後你有IGrouping<int, DocumentGroup>列表(如二維數組)

1 1 Name1  --| 
    1 Name2   -- <record 1 of IGrouping<int, DocumentGroup> 
    1 Name3  --| 
2 2 Name4   <record 2 of IGrouping<int, DocumentGroup>> 
3 3 Name5   <record 3 of IGrouping<int, DocumentGroup>> 

因此得到DocumentGroup你需要首先從Grouping項目來訪問,那麼你得到的DocumentGroup,例如:

var groupOfDocumentGroups = /* omitted code */ 
    select new DocumentGroup() { Name = dg.Namn, Id = dg.Id }) 
    .GroupBy(group => group.Id) 
    .ToList(); 

foreach(var groupItem in groupOfDocumentGroups) 
{ 
    // groupItem type is IGrouping<int, DocumentGroup> 
    // groupItem has `Key` property which is an integer of the Id. 
    // groupItem is also a collection that you can do enumeration. 
    foreach(var item in groupItem) 
    { 
     // there you go, item type is DocumentGroup 
    } 
} 

but I must have the group expression to filter it out

我假設你想獲得的所有獨特DocumentGroup S IN的所有DocumentType s,那麼Salman22答案就是你要找的。

在這種情況下,您也可以使用Distinct。如果你正在使用LINQ實體,你可以擁有。

var documentGroups = context.DocumentTypes 
    .Select(x => x.DocumentGroup) 
    .Distinct() 
    .ToList(); 

如果你正在使用LINQ合作對象,可以先實現IEqualityComparer<DocumentGroup>

class DocumentGroupComparer : IEqualityComparer<DocumentGroup> 
{ 
    public bool Equals(DocumentGroupx, DocumentGroupy) 
    { 
     return x.Id == y.Id; 
    } 
    public int GetHashCode(DocumentGroup obj) 
    { 
     return obj.Id.GetHashCode(); 
    } 
} 

var documentGroups = DocumentTypes 
    .Select(x => x.DocumentGroup) 
    .Distinct(new DocumentGroupComparer()) 
    .ToList();