2016-11-16 1 views
0

j'ai une classe appelée Person qui a les propriétés FirstName, LastName et MiddleName et j'ai SortedDictionary l'ensemble du formulaire (INTEGER, personne) appelée oPeople.LINQ SqlMethods.Like (et .Contains) ne

Sur , j'appelle une méthode qui charge une liste de 65 personnes. À l'heure actuelle, cela est codé en dur, mais je finirai par l'extraire d'une base de données.

Une fois que le formulaire est chargé, j'ai un TextBox appelé txtSearchForName pour l'utilisateur d'entrer un terme de recherche et que le système regarder à travers oPeople filtrage sur LastName pour un match complet ou partiel (insensible à la casse). Par la suite je voudrais pouvoir rechercher des comparaisons entre FirstName, LastName et MiddleName (s'il y en a un).

À ce stade, tout ce que je veux faire est de parcourir les résultats de la requête LINQ et de les afficher dans la fenêtre de la console.

est ici la classe Person:

Public Class Person 

    Private _fnm As String = String.Empty 
    Public Property FirstName() As String 
     Get 
      Return _fnm 
     End Get 
     Set(ByVal value As String) 
      _fnm = value.Trim 
     End Set 
    End Property 

    Private _lnm As String = String.Empty 
    Public Property LastName() As String 
     Get 
      Return _lnm 
     End Get 
     Set(ByVal value As String) 
      _lnm = value.Trim 
     End Set 
    End Property 

    Private _mnm As String = String.Empty 
    Public Property MiddleName() As String 
     Get 
      Return _mnm 
     End Get 
     Set(ByVal value As String) 
      _mnm = value.Trim 
     End Set 
    End Property 

    Public Sub New() 
    End Sub 

    Public Sub New(ByVal firstName As String, 
        ByVal lastName As String, 
        Optional ByVal middleName As String = "") 

     _fnm = firstName 
     _lnm = lastName 
     _mnm = middleName 

    End Sub 

End Class 

C'est la méthode que je utilise pour ajouter des personnes. J'ajoute 65 personnes, mais ont coupé le code vers le bas:

Private Sub FillPeopleDictionary() 

    Try 

     If oPeople.Count > 0 Then oPeople.Clear() 

     Dim oNewPerson As Person = Nothing 

     oNewPerson = New Person("Scarlett", "Johansson") 
     oPeople.Add(1, oNewPerson) 

     oNewPerson = New Person("Amy", "Adams") 
     oPeople.Add(2, oNewPerson) 

     oNewPerson = New Person("Jessica", "Biel") 
     oPeople.Add(3, oNewPerson) 

    Catch ex As Exception 

     MessageBox.Show(ex.Message, "Error [FillPeopleDictionary]", MessageBoxButtons.OK, MessageBoxIcon.Error) 

    End Try 

End Sub 

Ceci est ma déclaration LINQ suivie de la sortie de la console qui est appelée lorsque l'utilisateur clique sur un bouton:

Dim sSearchTerm As String = txtSearchForName.Text.Trim.ToLower 

Dim queryResults = From person In oPeople 
'Where SqlMethods.Like(person.Value.LastName.ToLower, "%" & sSearchTerm & "%") 
'Where person.Value.LastName.ToLower.Contains("%" & sSearchTerm & "%") 

Console.WriteLine("search term: " & sSearchTerm & 
        Environment.NewLine & Environment.NewLine & 
        "queryResults.Count: " & queryResults.Count.ToString & 
        Environment.NewLine) 

For Each result In queryResults 

    If Not String.IsNullOrEmpty(result.Value.MiddleName) Then 

     Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.MiddleName & " " & result.Value.LastName) 

    Else 

     Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.LastName) 

    End If 

Next 

Le LINQ La déclaration fonctionne telle quelle, sans condition, elle passe donc en boucle et liste correctement toutes les personnes de la collection oPeople.

Il existe deux clauses Where commentées ci-dessous l'instruction initiale queryResults. Ce sont les deux façons que j'essayais de filtrer. Une approche était d'utiliser .Contains et l'autre était d'utiliser .Like mais ne fonctionne pas.

Si l'utilisateur était de type "mar", j'espère revenir une liste de 6 personnes de la liste des 65 (insensible à la casse):

Meghan Markle
Margo Robbie
Kate Mara
Mary Elizabeth Winstead
Marian Rivera
Amy Smart

maintenant, bien sûr cela cherche sur FirstName et LastName. En ce moment j'essaye juste d'obtenir LastName pour fonctionner. Avec seulement la LastName la liste ne serait:

Meghan Markle
Kate Mara
Amy Smart

Quelqu'un peut-il voir ce que je fais mal ici?Ou devrais-je supprimer l'idée d'utiliser LINQ avec un SortedDictionary?

+2

Pourquoi utilisez-vous 'SqlMethods' sur une collection NET ordinaire commune? En outre, merci de poster 130 * lignes doubles espacées * montrant comment vous avez ajouté 60 personnes. La plupart d'entre nous obtiendrait l'idée après 2 ou 3. voir [MCVE] – Plutonix

+0

Plutonix - J'utilise SQLMethods seulement parce que j'essaye simplement de comprendre comment fonctionne LINQ. C'est la première fois que je l'utilise, donc je me suis dit qu'il valait mieux commencer par quelque chose avec lequel je suis un peu à l'aise (SortedDictionaries). Jinx88909 m'a montré qu'une liste (Of T) est une meilleure approche. –

+0

'SqlMethods' est pour Linq to SQL. vous n'en avez pas besoin pour en savoir plus sur linq ou les méthodes d'extension comme dans les réponses – Plutonix

Répondre

0

Modifiez votre classe Person pour inclure un PersonId et passez le comme oNewPerson = New Person(1, "Scarlett", "Johansson").

Remplacez le oPeople par List(Of Person) de sorte que lorsque vous l'ajoutez, cela ressemble à oPeople.Add(oNewPerson).

Votre déclaration LINQ alors ressembler à ceci:

Dim queryResults = From person In oPeople 
        Where person.FirstName.ToLower Like "*" & sSearchTerm & "*" Or 
         person.LastName.ToLower Like "*" & sSearchTerm & "*" 

Vous voudriez également changer le reste ne plus utiliser un dictionnaire:

For Each result In queryResults 

    If Not String.IsNullOrEmpty(result.MiddleName) Then 

     Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.MiddleName & " " & result.LastName) 

    Else 

     Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.LastName) 

    End If 

Next 

Hope this helps.

+1

Cela l'a corrigé. Comme j'essaye d'apprendre plus au sujet de LINQ j'ai une question. Est-ce que LINQ ne fonctionne pas avec les dictionnaires triés? Je ne suis pas contre l'utilisation de Listes (Of T) Je suis juste curieux. Merci d'avoir pris le temps de bien expliquer ce qui était en train de changer et de fournir le code. C'est très apprécié. –

+0

Oui, cela fonctionnerait encore, mais je pense qu'il serait utile de faire apparaître le PersonId dans la classe plutôt que d'avoir un dictionnaire, alors vous pouvez référencer la propriété plutôt que .Key pour l'Id ou .Value.FirstName. Pour moi, c'est juste un peu plus propre. Heureusement, il a résolu le problème. – Bugs

0

Votre 2ème Where clause tentative est proche, à l'exception de la fonction Contains il y a String.Contains qui n'utilise pas les % caractères génériques que SQL utilise, vous devez donc:

Dim queryResults = 
    From person In oPeople 
    Where person.Value.LastName.ToLower.Contains(sSearchTerm) 

Vous pouvez facilement ajouter un chèque de FirstName avec OrElse person.Value.FirstName.ToLower.Contains(sSearchTerm).

+0

Merci pour l'aide. Je suis allé avec la réponse de Jinx88909 d'en haut. J'ai incorporé votre suggestion de l'OrElse. Travaillé parfaitement. Merci pour l'aide. –

0

Changez votre requête Linq être comme suit:

Dim queryResults = From p In oPeople 
           Where p.Value.FirstName.ToLower.Contains(sSearchTerm) Or p.Value.LastName.ToLower.Contains(sSearchTerm) 
+0

J'ai essayé mais ça ne m'a toujours pas donné de résultats. Je ne suis pas sûr de ce que j'ai fait de mal. J'ai fini par aller avec la réponse de Jinx88909 d'en haut. Je vous remercie d'avoir pris le temps. C'est très apprécié. –