【发布时间】:2017-05-16 17:10:25
【问题描述】:
问题:我在 SQL Server 数据库上使用 SQLMetal 生成了一个 DataContext。该数据库具有 TableA,其中包含具有 Int64 标识符的实体。我的查询需要处理我在某些集合中查询具有 ID 的所有元素的情况。随着数据集的增长,这个集偶尔会包含超过 2100 个 ID。
我意识到这个问题与就该主题提出的其他问题相似,但我正在寻求帮助,构建一种扩展方法来解决该问题。
相关问题:
Avoiding the 2100 parameter limit in LINQ to SQL
Hitting the 2100 parameter limit (SQL Server) when using Contains()
我的代码如下所示:
var ids = new List<long>{ 1, 2, 3, /*...,*/ 2101};
var database = new MyDatabaseClass(connection)
var items = database
.TableA
.Where(x=>ids.Contains(x.RecordID))
.ToList();
并产生此错误:
传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。此 RPC 请求中提供的参数过多。最大值为 2100。
随着各种数据集的增长,我预计会经常遇到这个问题,我想创建一个通用扩展,可用于任何表。这个想法是将查询分解为更小的 Where Contains 查询,然后聚合结果。这是我试图展示我的想法之一:
public static List<TSource> WhereMemberInUniverse<TSource, TUniverse>(this IQueryable<TSource> source, Func<TSource, TUniverse> memberSelector, IEnumerable<TUniverse> universe)
{
var distinctUniverse = universe.Distinct().ToList();
int batchSize = 2000;
var result = new List<TSource>();
for (int i = 0; i < distinctUniverse.Count; i += batchSize)
{
var universeSlice = distinctUniverse.Skip(i).Take(batchSize);
var partialRes = source
.Where(x => universeSlice.Contains(memberSelector(x)));
result.AddRange(partialRes);
}
return result;
}
调用代码将修改为:
var ids = new List<long>{ 1, 2, 3, /*...,*/ 2101};
var database = new MyDatabaseClass(connection)
var items = database
.TableA
.WhereMemberInUniverse(x=>x.RecordID, ids);
现在这在“universeSlice.Contains”行上失败了:
方法 'System.Object DynamicInvoke(System.Object[])' 不支持 SQL 转换。
似乎我所做的每一次尝试都以类似的 SQL 翻译错误告终。
【问题讨论】:
-
您尝试过 XML 方法吗? SQL Server Central
标签: c# sql-server linq linq-to-sql