from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME
depts
是部门ID的列表(IEnumerable<int>
)
这个查询可以正常工作,直到您传递一个大列表(比如大约3000个部门ID)..然后我得到这个错误:
传入得表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.此RPC请求中提供得参数太多.最多为2100.
我将查询更改为:
var dept_ids = string.Join(" ", depts.ToStringArray());
from f in CUSTOMERS
where dept_ids.IndexOf(Convert.ToString(f.DEPT_id)) != -1
select f.NAME
使用IndexOf()
修正了这个错误,但是使查询变慢了。有没有其他方法可以解决这个问题?非常感谢。
6条答案
按热度按时间0pizxfdo1#
我的解决方案(
Guids
是您要筛选的id列表):pcww981p2#
为什么不用sql编写查询并附加实体呢?
我已经有一段时间没有在Linq工作了,但现在开始:
当然,你需要防止注射,但这应该不会太难。
t3irkdon3#
您可能希望查看一下LINQKit project,因为其中包含了一种批处理此类语句的技术来解决此问题。我相信其想法是使用PredicateBuilder将本地集合分解为更小的块,但我没有详细查看该解决方案,因为我一直在寻找一种更自然的方法来处理此问题。
不幸的是,从Microsoft's response to my suggestion到修复此行为,似乎没有为.NET Framework 4.0甚至后续的Service Pack设置解决此问题的计划。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984
最新消息:
我已经在MSDN论坛上打开了一些讨论,讨论是否要针对LINQ to SQL或ADO.NET Entity Framework修复此问题。请查看这些帖子以了解有关这些主题的更多信息,并查看我使用XML和SQL UDF提出的临时解决方案。
bqjvbblv4#
我也遇到过类似问题,我有两种解决方法。
1.基于ID的联接
为了获取不在列表中的值,我使用了Except方法或左连接。
更新
EntityFramework 6.2会成功执行下列查询:
jtw3ybtb5#
你的帖子是不久前的,但也许有人会从中受益。实体框架做了很多查询缓存,每次你发送一个不同的参数计数,它被添加该高速缓存中。使用“包含”调用将导致SQL生成一个子句,如“WHERE x IN(@p1,@p2.... @pn)",并膨胀EF缓存。
最近我寻找一种新的方法来处理这个问题,我发现你可以创建一个完整的数据表作为一个参数。
首先,您需要创建一个自定义表类型,因此在SQL Server中运行此命令(在我的示例中,我将自定义类型称为“TableId”):
然后,在C#中,可以创建一个DataTable,并将其加载到与该类型匹配的结构化参数中。可以根据需要添加任意数量的数据行:
这是要搜索的任意ID列表。您可以根据需要设置列表的大小:
使用自定义表类型和数据表创建SqlParameter:
然后,您可以从上下文中调用一些SQL语句,将现有的表与表参数中的值连接起来。这将为您提供与ID列表匹配的所有记录:
suzh9iv86#
在将depts作为参数传递给Linq生成的IN语句之前,你可以将depts列表划分为更小的集合。
Divide a large IEnumerable into smaller IEnumerable of a fix amount of item