如果不支持Contains,如何在LINQ to Entities(实体框架)中执行SQL样式的“IN”语句?

c# linq entity-framework linq-to-entities

11781 观看

5回复

13804 作者的声誉

我正在使用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)'方法,并且此方法无法转换为商店表达式。

有没有人有解决方法或其他解决方案?

作者: JC Grubbs 的来源 发布者: 2008 年 11 月 30 日

回应 (5)


7

10337 作者的声誉

决定

你需要使用这个:

.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;
作者: liggett78 发布者: 30.11.2008 09:42

-6

4066 作者的声誉

我的解决方法是将实体结果转换为List,然后应用Contains()。

例:

var items = db.InventoryItem
                .Include("Kind")
                .Include("PropertyValues")
                .Include("PropertyValues.KindProperty")
                .ToList()
                .Where(itm => valueIds.Contains(itm.ID));
作者: Stef Heyenrath 发布者: 03.02.2010 08:58

8

182606 作者的声誉

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

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]
)
作者: Drew Noakes 发布者: 13.12.2010 06:16

0

16549 作者的声誉

正如Diego B Vega在这篇文章中所提到的(第二个答案),Contains现在应该在EF4中工作。

作者: VVS 发布者: 15.12.2010 12:03

0

19 作者的声誉

Contains()和Any()未正确转换为SQL中的IN操作。使用lambda表达式时,该列(转换为EF或Linq中的属性为SQL)应位于lambda表达式的左侧。我在SQL中使用XEvent Profiler来正确跟踪抛出的实际查询,这就是它的外观。

例如这段代码:

List<int> ids = new List<int> {1, 2, 3};
IQueryable<Credits> creditsForUpdate = context.Credits.Where(c => unlistedCreditsIds.Any(a => a == c.CreditsId));
// it won't matter if you use .Any() or .Contains(),
// this won't be properly translated into how you want in in SQL statement.

从分析器转换为此SQL语句:

SELECT [c].[TenantID], [c].[CreditsID], [c].[ProjectID], [c].[CharacterName], [c].[CreditsLabel], [c].[CreditsOrder], [c].[Name], [c].[PriorCredits]
FROM [Credits] AS [c]
WHERE 0 = 1
作者: Jesse Gador 发布者: 07.12.2018 01:51
32x32