. net实体框架-使用.contains()在Where表达式中查找字节值

本文关键字:表达式 Where 查找 字节 框架 实体 使用 contains net | 更新日期: 2023-09-27 17:49:39

我正在根据我从用户获得的参数构建一个IQueryable。其中一个参数是多选择,我需要检索包含所选值的记录。

处理它的代码是:

var ids = parameters.DeliveryID.ToArray(); courses = courses.Where(c => ids.Contains(c.CourseDeliveryID));

在以上代码中:
1. id -是一个字节数组,我确保在调用Contains()之前它有多个值。
2. c.CourseDeliveryID——这是一个字节值。

在数据库中,我将CourseDeliveryID存储为tinyint (SQL Server 2008)。

编译很好。

当我运行代码时,我得到以下ArgumentException:
DbExpressionBinding requires an input expression with a collection ResultType.
Parameter name: input

我在这里找到了异常的文档:http://technet.microsoft.com/en-us/library/system.data.common.commandtrees.expressionbuilder.dbexpressionbuilder.bindas.aspx

当我试图解决这个问题时,我发现如果我在short, int或long上使用相同的代码,我没有任何问题。

我从昨天开始就和微软联系了,当我知道更多的时候会更新,但同时我想我也会把它扔到这里,如果可能的话,得到更多的建议。

提前感谢!

. net实体框架-使用.contains()在Where表达式中查找字节值

我能够在LINQPad中重现您的错误,并发现使用List<byte>而不是byte[]可以工作:

// byte[] ids = new byte[] { 1, 64 };  <== causes ArgumentException
List<byte> ids = new List<byte> { 1, 64};
var c = Courses.Where (co => ids.Contains(co.CourseDeliveryId));

将生成以下SQL并返回结果:

SELECT 
[Extent1].[CourseId] AS [CourseId], 
[Extent1].[CourseName] AS [CourseName], 
[Extent1].[CourseDeliveryId] AS [CourseDeliveryId]
FROM [dbo].[Courses] AS [Extent1]
WHERE [Extent1].[CourseDeliveryId] IN (1,64)
同样有趣的是,使用int[]short[]也可以工作,产生以下sql:

SELECT 
[Extent1].[CourseId] AS [CourseId], 
[Extent1].[CourseName] AS [CourseName], 
[Extent1].[CourseDeliveryId] AS [CourseDeliveryId]
FROM [dbo].[Courses] AS [Extent1]
WHERE (1 =  CAST( [Extent1].[CourseDeliveryId] AS int)) OR (64 =  CAST( [Extent1].[CourseDeliveryId] AS int))

但是使用byte[]会导致异常。我只能猜测SQL Server EF提供程序正试图以某种特殊的方式处理byte[],导致此异常

虽然使用不同的容器可以解决问题,但您不必更改容器类型。你只需要把它赋值给IEnumerable:

IEnumerable<byte> ids = parameters.DeliveryID.ToArray();
courses = courses.Where(c => ids.Contains(c.CourseDeliveryID));

(在这种特殊情况下,你可以使用ToList()而不是ToArray()但在一般情况下如果你得到字节数组而不想将其重建为列表,这就可以了)