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

あなたが参照した投稿のように、すぐに使用できるわけではありません。この投稿では、独自のクエリ プロバイダーの作成についても言及していますが、これは多少のオーバーヘッドと複雑さを伴うため、おそらく必要ありません。

ここにはいくつかのオプションがあります。

  1. コンパイルされたクエリを使用しないでください。むしろ、配列内の各項目から where 句を作成し、次のような結果になるメソッドを用意します (疑似コード)。

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

    各 OR 句を作成するには、ここで式を使用する必要があることに注意してください。

  2. SQL Server 2008 を使用している場合は、テーブル値パラメーターと再度比較する値を受け取るスカラー値関数を作成します。ビットが返されます (項目がテーブルの値に含まれているかどうかを示すため)。次に、データ コンテキストで LINQ-to-SQL を介してその関数を公開します。そこから、そのための CompiledQuery を作成できるはずです。この場合、IEnumerable<string>一連の文字列を表現する方法が複数ある可能性があるため、配列の代わりに (ユーザー名が文字列型であると仮定して) を使用する必要があることに注意してください。順序は関係ありません。

于 2009-12-28T18:30:25.280 に答える
1

私が自分でやっていることがわかった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 に答える