web-dev-qa-db-ja.com

VB.NETとLINQを使用して「where」句を追加するにはどうすればよいですか?

私はVB.NETにかなり慣れていないので、ここでは簡単だと思ったもので少しトラブルがあります。

シンプルに保ちながら、検索したい「名前」を含むドキュメントテーブルがあるとしましょう(実際には、他にもいくつかのテーブル、結合などがあります)。渡された文字列値に基づいてwhere句を使用してクエリを作成できる必要があります。

例-ユーザーは「ABC」、「ABC DEF」、「ABC DEF GHI」を渡すことができます。

最終的なクエリは次のようになります(構文が正しくないことはわかっています)。

Select * from Documents Where Name Like %ABC% AND Name Like %DEF% AND Name like %GHI%

だから、私はこのようなことができると思った。

Dim query = From document In _context.Documents

<< loop based on number of strings passed in >>
query = query.Where( ... what goes here?? )

何らかの理由で、頭がおかしいなどの理由で、VB.NETでこれを機能させる方法がわからず、正しく動作しているのかどうかわかりません。

27
sugarcrum

ここで注意が必要なのは、不明な数のクエリパラメーターだと思います。ここで、基礎となるLINQ IQueryable(Of T)を使用できます。

私は次のように動作すると思います(コンパイルされていません、ここではメモ帳のコードだけです):

Public Function GetDocuments(criteria as String)
    Dim splitCriteria = SplitTheCriteria(criteria)

    dim query = from document in _context.Documents

    For Each item in splitCriteria
        Dim localItem = item
        query = AddCriteriaToQuery(query, localItem)
    Next

    dim matchingDocuments = query.ToList()
End Function

Private Function AddCriteriaToQuery(query as IQueryable(Of Document), criteria as string) as IQueryable(Of Document)
     return query.Where(Function(doc) doc.Name = criteria)
End Function

LINQはクエリを遅延実行するため、ループ内のクエリにwhere句を追加し、最後に.ToList()を呼び出してクエリを実行できます。

10
Jeremy Wiebe

LINQ to SQLでは、質問で述べたように、クエリオブジェクトの.Whereメソッドを使用してクエリにWHERE句を追加できます。 LIKE演算子を使用するには、Whereメソッドの呼び出しのLambda式で、クエリしているオブジェクトの.Containsメソッドを使用してみてください。

コンソールアプリケーションの簡単な例を次に示します。うまくいけば、それが正しい方向にあなたを導くでしょう。

Public Class Doc

    Private _docName As String
    Public Property DocName() As String
        Get
            Return _docName
        End Get
        Set(ByVal value As String)
            _docName = value
        End Set
    End Property

    Public Sub New(ByVal newDocName As String)
        _docName = newDocName
    End Sub
End Class

Sub Main()
    Dim Documents As New List(Of Doc)
    Documents.Add(New Doc("ABC"))
    Documents.Add(New Doc("DEF"))
    Documents.Add(New Doc("GHI"))
    Documents.Add(New Doc("ABC DEF"))
    Documents.Add(New Doc("DEF GHI"))
    Documents.Add(New Doc("GHI LMN"))

    Dim qry = From docs In Documents

    qry = qry.Where(Function(d) d.DocName.Contains("GHI"))

    Dim qryResults As List(Of Doc) = qry.ToList()

    For Each d As Doc In qryResults
        Console.WriteLine(d.DocName)
    Next

End Sub

.WhereメソッドのLambda式の.Contains( "GHI")呼び出しに注意してください。式のパラメーター「d」を参照しています。このパラメーターは、DocNameプロパティを公開し、さらに.Containsメソッドを公開しています。これにより、期待するLIKEクエリが生成されます。

このメソッドは付加的です。つまり、クエリのWHERE句に追加のLIKE演算子を追加するために、.Whereメソッドの呼び出しをループで囲むことができます。

3
Bob Mc
Dim query = From document In _context.Documents where document.name = 'xpto' select document 

または

Dim query = From document In _context.Documents where document.name.contains('xpto') select document 
1
Sergio

ループでこれを行うと、次のようなことができます。

.Where(Function(i as mytype) i.myfiltervar = WhatIWantToSelect)
0
TheCodeMonk