下面的代碼有什麼問題?這爲什麼會在運行時間中捕獲?
var results = db.Departments.Select(x => customfunction(x.DepartmentID));
results.toList();
下面的代碼有什麼問題?這爲什麼會在運行時間中捕獲?
var results = db.Departments.Select(x => customfunction(x.DepartmentID));
results.toList();
這是爲什麼這不是在編譯時抓到,但給出了運行時異常?
有許多不同的LINQ提供程序允許您針對各種數據源(LINQ to Entities,LINQ to Objects,LINQ to XML等)使用LINQ。
雖然LINQ to Entities不知道如何調用自定義方法(至少不是公共數據庫的提供者),但是一些LINQ提供者可能很好理解如何執行myfunction
。編譯器沒有集成到所有的LINQ提供程序中,所以關於是否可以包含自定義方法的信息僅在運行時可用。
事實上,LINQ到對象可以執行它
var results = db.Departments
.AsEnumerable()
.Select(x => myfunction(x.DepartmentID));
的的
db.Departments.Select(x => myfunction(x.DepartmentID));
到SQL轉換不會發生,直到在運行過程中非常晚。
所以在編譯時Entity Framework並不知道myFunction不是它不知道如何轉換爲sql的東西。
當然你可以做
db.Departments.Select(x => (x * 2));
和EF會很樂意能夠轉換到SQL,但如果您嘗試使用在部門對象的自定義屬性不會映射到現場的分貝使用Linq數據提供者不知道如何轉換爲sql的自定義方法,您將得到相同的錯誤。
這個想法很簡單:在C#中永遠不會執行.Select(x => myfunction(x.DepartmentID))
。相反,實體框架分析此表達式並將其轉換爲SQL。例如,如果您在C#中調用.Count()
,EF會將其轉換爲SELECT COUNT(...)
這是非常強大的,除了少數情況下,例如您的情況。 EF通過Expression Trees分析您的代碼。 如果在表達式樹中調用myFunction()
,則不可能「擴展」該調用以獲取函數的主體。這是C#如何實現的限制。這就是爲什麼EF無法生成合理的SQL,因爲它不知道你的方法是幹什麼的。
然而,有一個合理的選擇:LinqKit
LinqKit將允許你寫在你的表情可重複使用的「功能」。
例子:
static string[] QueryCustomers (Expression<Func<Purchase, bool>> purchaseCriteria)
{
var data = new MyDataContext();
var query = from c in data.Customers.AsExpandable()
where c.Purchases.Any (purchaseCriteria.Compile())
select c.Name;
return query.ToArray();
}
你能否詳細說明嗎?我還不明白..! –
我更新了我的答案。 –