在LINQ中获得2100参数限制

时间:2015-08-04 10:59:07

标签: vb.net linq-to-sql

我在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

1 个答案:

答案 0 :(得分:0)

您可能希望将原始列表分区为较小的块。让我们说一下2000个元素,这会影响性能(特别是如果SQL Server版本不支持OFFSET nFETCH 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字符串(也是为了保持代码可以重用于其他数据类型,并且易于更新和重构)但是,从链接的帖子中,你应该从其中一个答案中尝试代码而不是不工作来自问题的代码......