.NET Entity Framework - 使用 .Contains() 在Where表达式中查找字节值

发布于 2024-10-31 19:22:10 字数 960 浏览 0 评论 0原文

我正在根据从用户那里获得的参数构建 IQueryable 。这些参数之一是多选,我需要检索包含任何选定值的记录。

处理这个问题的代码是:

var ids =parameters.DeliveryID.ToArray(); 课程 = course.Where(c => ids.Contains(c.CourseDeliveryID));

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

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

编译就好了。

当我运行代码时,我收到以下 ArgumentException:
<代码> DbExpressionBinding 需要带有集合 ResultType 的输入表达式。
参数名称:输入

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

在尝试解决问题时,我发现如果我在 Shorts、Ints 或 Longs 上使用相同的代码,我没有任何问题。

我从昨天开始就此事与微软联系,当我了解更多信息时我会进行更新,但与此同时,我想如果可能的话,我也会将其放在这里以获得更多建议。

提前致谢!

I am building an IQueryable based on parameters I get from the user. One of those parameters is a multi-select and I need to retrieve records that contain any of the selected values.

The code that deals with that is:


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

In the above code:
1. ids - is a byte array and I make sure it has multiple values before calling Contains().
2. c.CourseDeliveryID - that's a byte value.

In the database I store CourseDeliveryID as tinyint (SQL Server 2008).

Compilation is just fine.

When I run the code I get the following ArgumentException:

DbExpressionBinding requires an input expression with a collection ResultType.
Parameter name: input

I found the documentation for that exception here:
http://technet.microsoft.com/en-us/library/system.data.common.commandtrees.expressionbuilder.dbexpressionbuilder.bindas.aspx

While trying to solve the problem I found that if I use the same code on shorts, ints or longs I don't have any problem.

I'm in touch with Microsoft about it since yesterday and will update when I know more, but in the meantime I figured I'd throw it also here to get more advises if possible.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖 2024-11-07 19:22:10

我能够在 LINQPad 中重现您的错误,并发现使用 List 而不是 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[],从而导致此异常。

I was able to reproduce your error in LINQPad, and found that using a List<byte> instead of a byte[] would work:

// 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));

will generate the following sql and return results:

SELECT 
[Extent1].[CourseId] AS [CourseId], 
[Extent1].[CourseName] AS [CourseName], 
[Extent1].[CourseDeliveryId] AS [CourseDeliveryId]
FROM [dbo].[Courses] AS [Extent1]
WHERE [Extent1].[CourseDeliveryId] IN (1,64)

It's also interesting that using an int[] or short[] would also work, producing this 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))

but using a byte[] causes an exception. I can only guess that the SQL Server EF provider is trying to treat byte[] in some special way, resulting in this exception.

一桥轻雨一伞开 2024-11-07 19:22:10

尽管使用不同的容器可以解决问题,但您不必更改容器类型。
您需要做的就是将其分配给 IEnumerable:(

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

在这种特定情况下,您可以只使用 ToList() 而不是 ToArray(),但在一般情况下,如果您获得字节数组并且不想将其重建为列表,则可以这样做会做)

Although using different containers solve the issue, you do not have to change the container type.
All you need to do is assign it to IEnumerable:

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

(In this specific case you can just use ToList() instead of ToArray() but in the general case if you get the byte array and do not want to rebuild it as a list this will do)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文