2009-09-01 54 views
8

我已經擴展我的實體以實現其類型的特定接口。我試圖執行以下查詢:將linq結果轉換爲列表<MyInterface>

var results = from x in context.MyEntityTable 
       where x.AProperty == AValue 
       select x; 

return results.Count() > 0 ? results.Cast<IApplicationEntity>().ToList() : null; 

不過,我不斷收到以下錯誤:

「LINQ到實體只支持鑄造實體數據模型基本類型」

基本上什麼我想要做的是始終將原始實體類型的結果轉換爲它實現的接口的通用列表。

這可能嗎?

回答

20

你可以做客戶端上的演員,通過調用AsEnumerable擴展方法繞過實體框架查詢轉換層:

return results.Any() 
     ? results.AsEnumerable().Cast<IApplicationEntity>().ToList() 
     : null; 

然而,最好是反向做Count檢查的順序:

var list = results.AsEnumerable().Cast<IApplicationEntity>().ToList(); 
return list.Count == 0 ? null : list; 
+1

+1,但是這將執行兩個數據庫查詢(對於Count和ToList)......它可能會更好地先調用ToList,然後檢查項目數 – 2009-09-01 07:50:23

+0

@Thomas:查看第二個查詢。 – 2009-09-01 07:51:42

+0

是的,這是更好的;) – 2009-09-01 07:55:10

0
return results.Count() > 0 ? 
results.Select(result => (IApplicationEntity)result) 
.ToList() : null; 
+0

我不認爲它會工作,出於同樣的原因鑄造方法沒有。您需要將查詢轉換爲IEnumerable第一個 – 2009-09-01 07:51:58

+0

該消息指出它不知道如何將linq中的Cast()運算符轉換爲實體。這實際上是由linq提供者(例如,Linq到Sql,linq到對象等)編寫的代碼。 其他海報建議將調用改爲AsEnumerable以強制使用Linq到對象,並因此Cast()運算符成功。我正在做同樣的事情,但使用C#而不是通過明確投影到代碼中。試試吧,讓我知道它是否有效。 – Spence 2009-09-01 11:15:43

3

如果你想投你的結果是複雜類型,你需要強制代碼使用LINQ到對象,而不是LINQ到Entiti ES。

在投射之前調用AsEnumerable擴展方法是這裏的訣竅。

嘗試以下操作:

var results = from x in context.MyEntityTable 
       where x.AProperty == AValue 
       select x; 

return results.AsEnumerable().Cast<IApplicationEntity>().ToList(); 

另外請注意,這不是明智的檢查Count()在枚舉的,因爲這意味着在集合遍歷兩次。

+0

其實,這是行不通的。在演員陣容之前,你應該做'AsEnumerable' *。否則,EF將嘗試將其轉換爲查詢以在提供程序上運行。 – 2009-09-01 07:47:39

+0

@Mehrdad:爲了你自己的好,太快了。我在你的評論之前編輯了這篇文章。 ;) – Noldorin 2009-09-01 07:48:33

相關問題