如果不支持Contains,如何在LINQ to Entities(實體框架)中執行SQL樣式的“IN”語句?

c# entity-framework linq linq-to-entities

我正在使用LINQ to Entities(而不是LINQ to SQL),而且我在創建'IN'樣式查詢時遇到了麻煩。這是我目前的詢問:

var items = db.InventoryItem
                .Include("Kind")
                .Include("PropertyValues")
                .Include("PropertyValues.KindProperty")
                .Where(itm => valueIds.Contains(itm.ID)).ToList<InventoryItem>();

但是,當我這樣做時,拋出以下異常:

LINQ to Entities無法識別方法'Boolean Contains(Int64)'方法,並且此方法無法轉換為商店表達式。

有沒有人有解決方法或其他解決方案?

一般承認的答案

你需要使用這個:

.Where(string.Format("it.ID in {0}", string.Join(",", valueIds.ToArray())));

或動態構造WHERE部分,如本文所述

PS - 信息已更新,此答案更新如下,以保持相關性:

引用的鏈接包含以下更新:

...在EF4中,我們添加了對 Contains方法的 支持 ,至少在這個 特定情況下是對集合值 參數的支持。因此,這種 代碼現在可以直接使用, 並且不需要使用任何 附加表達式構建方法:

var statusesToFind = new List<int> {1, 2, 3, 4};
var foos = from foo in myEntities.Foos
           where statusesToFind.Contains(foo.Status)
           select foo;

熱門答案

在某些情況下,您可以使用Linq的Any擴展方法:

var userIds = new[] { 1, 2, 3 };

from u in Users
     where userIds.Any(i => i==u.Id)
     select u;

在這種情況下生成的SQL看起來很奇怪,但是像Linq-to-Entities生成的SQL一樣,對於人來說它可能過於冗長,但在實踐中運行速度很快。

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[DisplayName] AS [DisplayName], 
FROM [dbo].[Users] AS [Extent1]
WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM  (SELECT 
        [UnionAll1].[C1] AS [C1]
        FROM  (SELECT 
            1 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            2 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
    UNION ALL
        SELECT 
        3 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
    WHERE [UnionAll2].[C1] = [Extent1].[Id]
)


Related

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