2017-06-30 55 views
4

我正在尋找一種在複雜對象上執行GroupBy的方法,而不是一個屬性。問題是我想在IQueryable上這樣做,因爲在這種情況下從表中獲取所有數據是一個非常糟糕的主意。如何使用IQueryable對複雜對象執行GroupBy

我們使用的是Entity Framework 6.1。

類看起來是這樣的:

public class Pin { 
    public Guid Id {get;set;} 
    public Guid PageId {get;set;} /* this is the foreign key to our Pages-table */ 
    public PageClass Page {get;set;} /* this is a relation */ 
} 

我需要在時間的某一頁已經被「釘」報告,打印頁面的名稱爲好。

現在我的代碼如下所示:

var pinnedPages = GetAll().GroupBy(x => x, comparer); 

foreach (var pinnedPage in pinnedPages) 
{ 
    var numberOfTimesPinned = pinnedPage.Count(); 
    var pin = pinnedPage.Key; 

    //write a line to the report 
} 

但如果對我的PageId集團,pinnedPage.Key返回一個GUID,很明顯,而我需要爲我的報告需要整個Page對象。

我也嘗試過實現自定義比較器,但是這不能被轉換爲SQL,顯然這就是爲什麼這也不起作用。

+0

顯然,'GetAll()'返回'IEnumerable'。你可以去'IQueryable'嗎? –

+0

也請顯示'Page'類。 –

回答

1
GetAll().GroupBy(x => x.pageId).Select(_ => new {key = _.Key, page = _.FirstOrDefault().Page, count = _.Count()}); 

通過在PAGEID這將組,但選擇將創建一個新的匿名對象將包含密鑰(PAGEID)並選擇第一個PageClass對象

+1

只需注意,Grouping對象已經包含了分組行,所以在foreach循環中'var page = pinnedPage.First()。Page;'也會得到第一個頁面對象。然而,將它包含在Select中會爲SQL優化留下更多空間,儘管我會在首先分組之前檢查null(如果相關的'.Where(x => x.Page!= null)'),而不是返回空的頁面數據與FirstOrDefault()。 – 8DX

+0

非常感謝,這解決了我的問題! –

1

你不需要如有分組你直接查詢頁面和使用,我認爲存在(或者應該加入)導航屬性:

var pinnedPages = context.Pages 
         .Select(p => new 
             { 
              Page = p 
              Pins = p.Pins.Count() 
             }); 

foreach (var pinnedPage in pinnedPages) 
{ 
    var numberOfTimesPinned = pinnedPage.Pins; 
    var pin = pinnedPage.Page; 

    //write a line to the report 
} 

我用context.Pages因爲聲明的來源應該是IQueryableGetAll返回IEnumerable(顯然,否則帶有比較器的GroupBy重載將不起作用)。