2016-02-12 96 views
5

我有一個非常奇怪的問題:ToList()擴展方法未能將結果轉換爲列表。這裏是我的代碼,標準的樣板LINQ查詢,我轉換ToList()兩次很好的措施Linq ToList()無法觸發立即執行

var assets = new List<Asset>(); 

using (var ctx = new LeaseContext()) 
{ 
    assets = ctx.Assets.OrderBy(o => o.Reference).Where(w => w.Status == AssetStatus.Active).ToList(); 

    assets.ToList(); 
} 

return assets; 

但資產仍是System.Data.Entities.DynamicProxies列表....

我從來沒有過這個問題。

+0

爲什麼你使用ToList()作爲同一個變量? –

+0

由於不使用ToList()的結果,所以第二個'ToList()'什麼也不做。 –

+0

我知道第二個ToList()是多餘的,我只是想測試。 – franklores

回答

8

原因是延遲加載。在EF中啓用延遲加載時(默認情況下),然後(再次,默認情況下)EF爲每個實體創建動態代理。這是加載相關實體所必需的。動態代理將從實體類繼承。所以在你的情況下,它將從Asset繼承。但動態代理將參考創建其實例的上下文。它將覆蓋導航屬性(這是虛擬的),通過存儲在動態代理中的上下文來查詢實體。

將派生類型的實例添加到基本類型列表是完全合法的。

如果你不想使用動態代理,那麼就禁用延遲加載和代理的創建:

ctx.Configuration.LazyLoadingEnabled = false; // turn-off loading on-demand 
ctx.Configuration.ProxyCreationEnabled = false; // turn-off wrapper class generation 

技術上你可以關閉代理生成和延遲加載將無法正常工作。但我更願意明確關閉這兩個設置。

+0

我已添加該聲明,但仍無效。 使用(VAR CTX =新LeaseContext()) \t \t \t { \t \t \t \t ctx.Configuration.LazyLoadingEnabled = FALSE; (=> w.Status == AssetStatus.Active).Select(x => x).ToList();其中, \t \t \t} \t \t \t \t \t \t收益資產; – franklores

+0

@franklores在使用'cxt'查詢資產之前,您應該添加此語句 –

+0

@franklores抱歉,我忘記了第二個配置設置 - 有一個用於禁用代理創建的單獨配置 –