60
from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME

deptsIEnumerable<int>是一个部门 ID列表 ( )

这个查询工作正常,直到你传递一个大列表(比如大约 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

usingIndexOf()修复了错误,但使查询变慢。有没有其他方法可以解决这个问题?非常感谢。

4

5 回答 5

15

我的解决方案(Guids是您要过滤的 id 列表):

List<MyTestEntity> result = new List<MyTestEntity>();
for(int i = 0; i < Math.Ceiling((double)Guids.Count / 2000); i++)
{
    var nextGuids = Guids.Skip(i * 2000).Take(2000);
    result.AddRange(db.Tests.Where(x => nextGuids.Contains(x.Id)));
}
this.DataContext = result;
于 2014-02-11T17:43:23.070 回答
6

为什么不在 sql 中编写查询并附加您的实体?

我在 Linq 工作已经有一段时间了,但这里是:

IQuery q = Session.CreateQuery(@"
         select * 
         from customerTable f
         where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);

当然,您需要防止注射,但这不应该太难。

于 2009-03-17T21:54:05.937 回答
1

我有类似的问题,我有两种方法来解决它。

  1. 相交
  2. 加入ID

要获取不在列表中的值,我使用了方法或左连接。

更新

EntityFramework 6.2 成功运行以下查询:

var employeeIDs = Enumerable.Range(3, 5000);
var orders =
    from order in Orders
    where employeeIDs.Contains((int)order.EmployeeID)
    select order;
于 2012-11-12T14:05:45.190 回答
1

您将需要查看LINQKit 项目,因为其中某处有一种将此类语句批处理以解决此问题的技术。我相信这个想法是使用 PredicateBuilder 将本地集合分解成更小的块,但我没有详细审查解决方案,因为我一直在寻找一种更自然的方法来处理这个问题。

不幸的是,从Microsoft 对我修复此行为的建议的回应看来,没有计划为 .NET Framework 4.0 甚至后续的服务包解决此问题。

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984

更新:

我已经在 MSDN 论坛上展开了一些关于是否要针对LINQ to SQLADO.NET 实体框架修复此问题的讨论。请参阅这些帖子以获取有关这些主题的更多信息,并查看我使用 XML 和 SQL UDF 提出的临时解决方法。

于 2009-08-04T19:00:31.280 回答
-1

在将部门列表作为参数传递给 Linq 生成的 IN 语句之前,您始终可以将它们划分为更小的集合。看这里:

将较大的 IEnumerable 划分为固定数量的项目的较小 IEnumerable

于 2015-05-23T15:45:38.967 回答