2011-11-07 46 views
1

我收到錯誤:Asp.net MVC錯誤:LINQ到實體不承認

LINQ到實體無法識別方法「PagedList.IPagedList 1[MvcMusicStore.Models.Album] ToPagedList[Album](System.Collections.Generic.IEnumerable 1 MvcMusicStore.Models.Album],的Int32, INT32)」的方法,而這種方法不能被翻譯成店表達

對於我下面的控制器操作:

public ActionResult Browse(string genre, int?page) 
    { 
     // Retrieve Genre and its Associated Albums from database 
     int pageIndex = page ?? 1; 
     var genreModel = storeDB.Genres.Where(g => g.Name == genre) 
             .Select(g => new GenreAlbumView 
             { 
              ID = g.GenreId, 
              Name = g.Name, 
              Albums = g.Albums.ToPagedList(pageIndex, PageSize) 
             }).SingleOrDefault(); 
     return View(genreModel); 
    } 

什麼可以的原因,並解決這個問題?

回答

2

首先運行genermodel查詢:

var genreModel = storeDB.Genres.Where(g => g.Name == genre).SingleOrDefault(); 

然後運行你的選擇。

因爲lin2entity具有有限的功能支持,不能將你的函數:

g.Albums.ToPagedList(pageIndex, PageSize) 

一個撥SQL命令,實際上它不能爲它創建相關表達式樹,所以你應該首先得到實體和然後選擇您想要的方式。

如果您應該在數據庫中進行這樣的分頁,請創建一個存儲過程並使用它。

+0

感謝兄弟,但我不確定哪些答案標記爲接受:-)。這兩個答案的工作,我不知道哪個更好。 –

+0

@Pankaj希望這可以幫助你,如果兩個答案都有相同的價值,你翻轉硬幣:) –

+0

大聲笑...我把這個標記爲答案becoz它看起來更好的方法。而且,我也沒有找到任何理由或情況時,應該選擇跳過並接管這種方法。 –

1

問題是,ToPagedList方法不是可以轉換爲SQL查詢並在數據庫中執行的東西。

對於數據庫服務器上的分頁,可以使用Skip和Take方法。

嘗試以下操作:

var genreModel = storeDB.Genres.Where(g => g.Name == genre) 
             .Select(g => new GenreAlbumView 
             { 
              ID = g.GenreId, 
              Name = g.Name, 
              Albums = g.Albums.Skip(PageSize * (PageIndex -1)).Take(PageSize) 
             }).SingleOrDefault(); 

當您使用跳過/送它可以被轉換成一個SQL命令時,尋呼將在數據庫服務器上完成,但是當你第一次執行查詢,然後調用ToPagedList方法你會有一個性能問題。然後在內存中執行分頁,從所有已從數據庫加載的相冊中執行分頁。

這個原理與Linq所謂的Deffered Execution有關。 當您執行表達式樹(例如使用Single,ToList,First,Count或類似方法)Sql命令在數據庫服務器上生成並執行時,您正在構建只在SQL中進行了轉換的表達式樹。

因此,如果您第一次調用'ToList'然後調用分頁,您將從數據庫中獲取所有記錄,並將它們分頁到內存中,這會慢很多。

+0

感謝隊友撫摸更深層次的問題,讓我明白爲什麼會發生這種情況。 –

+0

對不起隊友我標誌着賽義德答案被接受,因爲它看起來乾淨的編碼和更好的方法。但是,當你喜歡或需要使用跳過/接管Saeed的方法時,你能幫助我理解任何情況嗎? –