1

我正在使用以下 LINQ to SQL 编译查询。

 private static Func<MyDataContext, int[], int> MainSearchQuery =
     CompiledQuery.Compile((MyDataContext db, int[] online ) =>
              (from u in db.Users where online.Contains(u.username)
               select u));

我知道不可能将序列输入参数用于已编译的查询,并且在运行它时出现“参数不能是序列”错误

在此处相关的另一篇文章中,我看到有一些解决方案,但我无法理解。

有谁知道使用带有数组的编译查询作为输入参数?

如果你这样做,请发布示例。

4

2 回答 2

1

Like the post that you referenced, it's not really possible out of the box. The post also references creating your own query provider, but it's a bit of overhead and complexity that you probably don't need.

You have a few options here:

  1. Don't use a compiled query. Rather, have a method which will create a where clause from each item in the array resulting in something like this (psuedo-code):

    where 
        online[0] == u.username ||
        online[1] == u.username ||
        ...
        online[n] == u.username
    

    Note that you would have to use expression here to create each OR clause.

  2. If you are using SQL Server 2008, create a scalar valued function which will take a table-valued parameter and a value to compare againt. It will return a bit (to indicate if the item is in the values in the table). Then expose that function through LINQ-to-SQL on your data context. From there, you should be able to create a CompiledQuery for that. Note that in this case, you should take an IEnumerable<string> (assuming username is of type string) instead of an array, just because you might have more than one way of representing a sequence of strings, and to SQL server for this operation, it won't matter what the order is.

于 2009-12-28T18:30:25.280 回答
1

我发现自己正在做的一种解决方案(针对 MS SQL 2005/2008)。而且我不确定在所有情况下是否都适合只编写动态 sql 并使用 ExecuteQuery 方法针对数据上下文执行它。

例如,如果我有一个无界列表,我试图将其传递给查询以执行包含...

' Mock a list of values
Dim ids as New List(of Integer)
ids.Add(1)
ids.Add(2)
' ....
ids.Add(1234)

Dim indivs = (From c In context.Individuals _
                    Where ids.Contains(c.Id) _
                    Select c).ToList

我会修改此查询以创建一个 SQL 字符串,以便直接对数据库执行,就像这样......

Dim str As New Text.StringBuilder("")
Dim declareStmt as string = "declare @ids table (indivId int) "  & vbcrlf)

For i As Integer = 0 To ids.Count - 1

     str.Append("select " & ids(i).ToString() & " & vbcrlf)

     If i < ids.Count Then
          str.Append("union " & vbcrlf)
     End If

Next

Dim selStatement As String = "select * From " & context.Mapping.GetTable(GetType(Individuals)).TableName & _
      " indiv " & vbcrlf & _
      " inner join @ids ids on indiv.id = ids.id"

Dim query = declareStmt & str.ToString & selStatement
Dim result = context.ExecuteQuery(of Individual)(query).ToList

因此,除非我编码的任何语法错误或错误(以上或多或少是伪代码且未经测试),否则以上将在 SQL 中生成一个表变量并针对所需表执行内部连接(本例中为个人)并避免使用“IN”语句。

希望能帮助别人!

于 2010-04-28T13:02:48.033 回答