我正在根据我从用户获得的参数构建一个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上使用相同的代码,我没有任何问题。
我从昨天开始就和微软联系了,当我知道更多的时候会更新,但同时我想我也会把它扔到这里,如果可能的话,得到更多的建议。
提前感谢!
我能够在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()但在一般情况下如果你得到字节数组而不想将其重建为列表,这就可以了)