我在LINQ to SQL查询中收到2100参数限制错误。这是返回id列表的过程。参数l
有超过5000个id。
Public Function GetByID(ByVal l As List(Of Int32)) As List(Of OfficeAccess)
Return (From d In db.OfficeAccess
Where l.Contains(d.ID)
Order By d.ID Ascending Select d).ToList()
End Function
我已经尝试了Hitting the 2100 parameter limit (SQL Server) when using Contains()第二部分中给出的解决方案,但我需要另一种解决方案,而无需手动构建SQL查询字符串,这不起作用:
Dim ids = String.Join(" ", l.ToArray())
Return(From d In db.OfficeAccess
Where ids.IndexOf(Convert.ToString(d.ID)) != -1
Order By d.ID Ascending Select d).ToList()
更新
我使用了以下代码并且工作正常。
Dim l As New List(Of OfficeAccess)
Dim f As Int32, t As List(Of Int32)
While (ids.Count > 0)
If (ids.Count < 2000) Then f = ids.Count Else f = 2000
t = ids.GetRange(0, f)
l.AddRange((From d In db.OfficeAccess Where t.Contains(d.ID) Select d).ToList())
ids.RemoveRange(0, f)
End While
答案 0 :(得分:0)
您可能希望将原始列表分区为较小的块。让我们说一下2000个元素,这会影响性能(特别是如果SQL Server版本不支持OFFSET n
和FETCH NEXT m ROWS
),但它会解决您的问题。
Function Partition(ByVal l As List(Of Integer)) As List(Of OfficeAccess)
Const size As Integer = 2000
Dim result As List(Of OfficeAccess) = new List(Of OfficeAccess)
Dim index As Integer = 1
Dim partition As List(Of Integer) = (
From item In l
Take size
).ToList()
While partition.Any()
result.AddRange(
From d In db.OfficeAccess
Where partition.Contains(d.ID)
Order By d.ID Ascending
Select d
)
partition = (
From item in l
Skip index * size
Take size
).ToList()
index += 1
End While
Return result
End Function
请注意代码未经测试,然后准备好语法错误!
注意:在此示例中,我将部分结果累积到result
列表中,但您可以将每个枚举与Enumerable.Concat()
连接(将result
声明为IEnumerable(Of OfficeAccess)
并执行ToList()
}一次:Return result.ToList()
。它不应该产生任何(可见的)差异,除非你有大量的记录(因为,至少,你避免为每次批量插入调整result
)或者除非LINQ足够聪明以优化(某种方式)完整的结果查询(作为多个查询的串联)。
<子> 如果可能的话,我会避免手动构建SQL字符串(也是为了保持代码可以重用于其他数据类型,并且易于更新和重构)但是,从链接的帖子中,你应该从其中一个答案中尝试代码而不是不工作来自问题的代码...... 子>