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

我正在使用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(); 

但是,当我这样做时,抛出以下exception:

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 {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] ) 

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

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

例:

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