2009-05-18 55 views
77

爲什麼我得到的錯誤:實體框架 - 「無法創建類型‘閉合式’...的恆定值」的錯誤

Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.

當我嘗試列舉以下Linq查詢?

IEnumerable<string> searchList = GetSearchList(); 
using (HREntities entities = new HREntities()) 
{ 
    var myList = from person in entities.vSearchPeople 
    where upperSearchList.All((person.FirstName + person.LastName) .Contains).ToList(); 
} 

更新: 如果我嘗試以下方法只是爲了嘗試找出問題,我得到了同樣的錯誤:

where upperSearchList.All(arg => arg == arg) 

所以看起來這個問題是與所有的方法,對?有什麼建議麼?

回答

67

它看起來就像你正在試圖做的「WHERE ... IN」的條件等同。查看How to write 'WHERE IN' style queries using LINQ to Entities以查看如何使用LINQ to Entities執行此類查詢的示例。

此外,我認爲錯誤信息在這種情況下特別沒有幫助,因爲.Contains後面沒有括號,這會導致編譯器將整個謂詞識別爲lambda表達式。

+0

謝謝丹尼爾。對於普通的Linq,相同的語法可以正常工作。所以,它看起來像問題是EF。NET 3.5 SP1的權利? 不帶圓括號的包含相當於: 其中upperSearchList.All(x =>(person.FirstName + person.LastName).Contains(x))。ToList(); – 2009-05-18 21:12:50

11

我已經花了近6個月爭奪這一限制與EF 3.5,雖然我不是最聰明的人在世界上,我敢肯定我有用提供關於這一主題的東西。

通過種植的「OR風格」表達會導致不良的查詢執行計劃50英里高樹生成的SQL。我正在處理幾百萬行,影響很大。

有一個小黑客,我發現做一個SQL「中」,可以幫助,如果你只是在尋找通過ID一堆實體:

private IEnumerable<Entity1> getByIds(IEnumerable<int> ids) 
{ 
    string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray()); 
    return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}"); 
} 

其中pkIDColumn是你的主鍵id列名你的Entity1表。

但請繼續閱讀!

這是好的,但它需要的是我已經有什麼,我需要找到的ID。有時候我只想讓自己的表達能夠進入其他關係,而我所擁有的就是這些關聯關係的標準。

如果我有更多的時間我會嘗試直觀地表示這一點,但我不這麼只研究這句話了一下:考慮一個架構一個人,GovernmentId和GovernmentIdType表。 Andrew Tappert(Person)有兩張身份證(GovernmentId),一張來自俄勒岡州(GovernmentIdType),一張來自華盛頓(GovernmentIdType)。

現在從它生成一個edmx。

現在想象一下,你想找到所有具有一定ID值的人,說什麼1234567

這可以用一個單一的數據庫,這個命中完成:

dbContext context = new dbContext(); 
string idValue = "1234567"; 
Expression<Func<Person,bool>> expr = 
    person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue)); 

IEnumerable<Person> people = context.Person.AsQueryable().Where(expr); 

你看到的子查詢這裏?生成的sql將使用「連接」而不是子查詢,但效果相同。這些天SQL服務器優化子查詢到反正在幕後加入,但無論如何...

這一工作的關鍵是。任何在表達式內。

0

我得到這個錯誤消息時在。所有函數中使用我的數組對象爲空 我初始化數組對象,後(upperSearchList在你的情況下),錯誤消失 錯誤消息誤導了在這種情況下

其中upperSearchList.All(ARG => person.someproperty.StartsWith(ARG)))

8

我已經發現了錯誤(我使用框架4.5)的原因。問題是,在「Contains」參數中傳遞的EF複雜類型無法轉換爲SQL查詢。 EF可以在SQL查詢中只有簡單的類型,如int,字符串使用...

this.GetAll().Where(p => !assignedFunctions.Contains(p)) 

GETALL提供對象的列表具有複雜類型(例如:「功能」)。因此,我會試着在我的SQL查詢中接收這種複雜類型的實例,這自然不能工作!

如果我可以從我的名單中提取,這是適合我的搜索參數,我可以使用:

var idList = assignedFunctions.Select(f => f.FunctionId); 
this.GetAll().Where(p => !idList.Contains(p.FunktionId)) 

現在EF不再具有複合型「功能」的工作,但如用一個簡單的鍵入(長)。這工作正常!

相關問題