實體框架 - “無法創建類型'閉包類型'的常量值...”錯誤

entity-framework linq

為什麼我會收到錯誤:

無法創建“閉包類型”類型的常量值。在此上下文中僅支持基本類型(例如Int32,String和Guid)。

當我嘗試枚舉以下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) 

所以看起來問題出在All方法上,對吧?有什麼建議?

一般承認的答案

看起來你正試圖做相當於“WHERE ... IN”的條件。查看如何使用LINQ to Entities編寫'WHERE IN'樣式查詢,以獲取如何使用LINQ to Entities進行該類型查詢的示例。

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


熱門答案

過去6個月我一直在與EF 3.5爭奪這個限制,雖然我不是世界上最聰明的人,但我很確定我在這個主題上有一些有用的東西。

通過增長50英里高的“OR style”表達式生成的SQL將導致查詢執行計劃不佳。我正在處理幾百萬行,影響很大。

我發現做一個SQL'in'有點麻煩,如果你只是通過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是Entity1表的主鍵id列名。

但繼續閱讀!

這很好,但它要求我已經擁有了我需要找到的東西。有時我只是希望我的表達能夠與其他關係聯繫起來,而我所擁有的是那些相關關係的標準。

如果我有更多的時間,我會嘗試直觀地表示這一點,但我不會那麼只研究這句話:考慮一個帶有Person,GovernmentId和GovernmentIdType表的模式。 Andrew Tappert(人)有兩張身份證(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將使用'join'而不是子查詢,但效果是相同的。這些天SQL服務器無論如何都將子查詢優化為連接下的連接,但無論如何......

這項工作的關鍵是表達式中的.Any。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因