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

我正在根据我从用户那里获得的参数构建一个IQueryable。其中一个参数是多选,我需要检索包含任何选定值的记录。 处理它的代码是:
var ids = parameters.DeliveryID.ToArray();
courses = courses.Where(c => ids.Contains(c.CourseDeliveryID));
在上面的代码中: 1. ids - 是一个字节数组,我确保它在调用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 在尝试解决问题的过程中,我发现如果我在短裤,整体或多头上使用相同的代码,我就没有任何问题。 我从昨天起就与微软就这件事情进行过接触,并会在我了解更多时更新,但与此同时我想我也会把它扔到这里,以便在可能的情况下获得更多建议。 提前致谢!     
已邀请:
我能够在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(),但在一般情况下,如果您获得字节数组并且不想将其重建为列表,则可以这样做)     

要回复问题请先登录注册