web-dev-qa-db-fra.com

Comment ajouter une clause «where» à l'aide de VB.NET et LINQ?

Je suis assez nouveau sur VB.NET et j'ai un peu de mal ici avec quelque chose que je pensais être simple.

Pour rester simple, disons que j'ai une table de document avec "Nom" sur laquelle je veux chercher (en réalité, il y a plusieurs autres tables, jointures, etc.). J'ai besoin de pouvoir créer la requête à l'aide d'une clause where basée sur les valeurs de chaîne transmises.

Exemple - l'utilisateur peut passer "ABC", "ABC DEF", "ABC DEF GHI".

La dernière requête serait (la syntaxe n'est pas correcte, je sais):

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

Donc, je pensais que je pouvais faire quelque chose comme ça.

Dim query = From document In _context.Documents

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

Pour une raison quelconque, étant mort cérébral ou quelque chose, je ne peux pas comprendre comment faire fonctionner cela dans VB.NET, ou si je le fais correctement.

27
sugarcrum

Je crois que c'est ainsi que vous le feriez dans VB (je suis développeur C #):

query = query.where(Function(s) s = "ABC")

Voir LINQ - Exemples de requêtes pour quelques exemples.

41
Jimmie R. Houts

Je pense que la partie délicate ici est le nombre inconnu de paramètres de requête. Vous pouvez utiliser le LINQ IQueryable (Of T) sous-jacent ici pour vous aider.

Je pense que ce qui suit fonctionnerait (ce n'est pas compilé, juste du code bloc-notes ici):

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

Étant donné que LINQ retardera l'exécution de la requête, vous pouvez ajouter des clauses where à votre requête dans la boucle, puis appeler .ToList () à la fin pour exécuter la requête.

10
Jeremy Wiebe

Dans LINQ to SQL, vous pouvez ajouter des clauses WHERE à votre requête à l'aide de la méthode .Where de l'objet de requête, comme vous l'avez noté dans votre question. Pour utiliser l'opérateur LIKE, essayez d'utiliser la méthode .Contains de l'objet que vous interrogez dans l'expression Lambda de votre appel à la méthode Where.

Voici un exemple simplifié dans une application console. J'espère que cela vous mènera dans la bonne direction.

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

Notez l'appel .Contains ("GHI") dans l'expression Lambda de la méthode .Where. Je fais référence au paramètre de l'expression, "d", qui expose la propriété DocName, qui expose davantage la méthode .Contains. Cela devrait produire la requête LIKE que vous attendez.

Cette méthode est additive, c'est-à-dire que l'appel à la méthode .Where peut être inclus dans une boucle pour ajouter des opérateurs LIKE supplémentaires à la clause WHERE de votre requête.

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

Ou

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

Si vous faites cela en boucle, vous pouvez faire quelque chose comme ceci:

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