from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME
depts
是部门ID的列表(IEnumerable<int>
)
此查询正常工作,直到您传递一个大型列表(比如大约3000个dept 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()
修复了错误但使查询变慢。有没有其他方法可以解决这个问题?非常感谢。
答案 0 :(得分:12)
我的解决方案(指南 - &gt; Guid列表):
List<tstTest> tsts = new List<tstTest>();
for(int i = 0; i < Math.Ceiling((double)Guides.Count / 2000); i++)
{
tsts.AddRange(dc.tstTests.Where(x => Guides.Skip(i * 2000).Take(2000).Contains(x.tstGuid)));
}
this.DataContext = tsts;
答案 1 :(得分:7)
为什么不在sql中编写查询并附加你的实体?
自从我在Linq工作以来已经有一段时间了,但是这里有:
IQuery q = Session.CreateQuery(@"
select *
from customerTable f
where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);
当然,你需要防止注射,但这不应该太难。
答案 2 :(得分:1)
您需要查看LINQKit project,因为在某处某处是一种用于批处理此类语句以解决此问题的技术。我相信这个想法是使用PredicateBuilder将本地集合分解成更小的块,但我没有详细检查解决方案,因为我反而一直在寻找一种更自然的方法来处理这个问题。
不幸的是,从Microsoft's response to my suggestion出现了解决此行为的问题,即没有计划为.NET Framework 4.0或后续服务包解决此问题。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984
更新:
我已经就MSDN论坛上的LINQ to SQL或ADO.NET Entity Framework是否修复了问题进行了讨论。有关这些主题的更多信息,请参阅这些帖子,并查看我使用XML和SQL UDF提出的临时解决方法。
答案 3 :(得分:0)
我有类似的问题,我有两种方法可以解决它。
答案 4 :(得分:-1)
在将depts列表作为参数传递给Linq生成的IN语句之前,您总是可以将depts列表分割为更小的集合。见这里:
Divide a large IEnumerable into smaller IEnumerable of a fix amount of item