How to make Lambda in LINQ actually filter for linq dynamic

advertisements

Example-I have a person class

Public Class Person
Private _fname As String
Public Property Fname() As String
    Get
        Return _fname
    End Get
    Set(ByVal value As String)
        _fname = value
    End Set
End Property
Private _lname As String
Public Property Lname() As String
    Get
        Return _lname
    End Get
    Set(ByVal value As String)
        _lname = value
    End Set
End Property
Private _age As Integer
Public Property Age() As Integer
    Get
        Return _age
    End Get
    Set(ByVal value As Integer)
        _age = value
    End Set
End Property

End Class

  Dim people As New List(Of Person)
    people.Add(New Person With {.Fname = "Alice", .Lname = "Apples", .Age = 1})
    people.Add(New Person With {.Fname = "Bob", .Lname = "Banana", .Age = 2})
    people.Add(New Person With {.Fname = "Charlie", .Lname = "Cherry", .Age = 3})
    people.Add(New Person With {.Fname = "Dave", .Lname = "Durian", .Age = 4})
    people.Add(New Person With {.Fname = "Eric", .Lname = "EggPlant", .Age = 10})

    Dim filteredPerson = From person In people
    filteredPerson.Where(Function(fp) fp.Fname = "Bob")

    Dim finalList = filteredPerson.ToList
    For Each p In finalList
        Debug.Print("FNAME: " + p.Fname)
    Next

This still returns all 5 people, like the where is not being applied, what am I doing wrong?

I would also like to be able to pass a list of names and return only those

  Dim searchList As New List(Of String)
    searchList.Add("Bob")
    searchList.Add("Dave")

    Dim filteredPerson = From person In people
    For Each s In searchList
        Dim innerName As String = s
        filteredPerson.Where(Function(fp) fp.Fname = innerName)
    Next
    Dim finalList = filteredPerson.ToList
    For Each p In finalList
        Debug.Print("FNAME: " + p.Fname)
    Next


The problem is that Where doesn't change the collection. It returns the newly filtered collection.

Try this:

 Dim filteredPerson = people.Where(Function(fp) fp.Fname = "Bob")

(By the way, I don't see anything dynamic in here... where are you using dynamic LINQ?)

To add multiple Where clauses, you'll want something like this:

Dim searchList As New List(Of String)
searchList.Add("Bob")
searchList.Add("Dave")

Dim filteredPerson As IEnumerable(Of String) = people
For Each s In searchList
    Dim innerName As String = s
    filteredPerson = filteredPerson.Where(Function(fp) fp.Fname = innerName)
Next
Dim finalList = filteredPerson.ToList
For Each p In finalList
    Debug.Print("FNAME: " + p.Fname)
Next

However, I don't believe that's actually what you want to do. Each Where clause is going to insist that Fname is the specified name - and it's not going to be both Bob and Dave! I think you actually want something which can be expressed much more simply:

Dim searchList As New List(Of String)
searchList.Add("Bob")
searchList.Add("Dave")

Dim filteredPerson = people.Where(Function(fp) searchList.Contains(fp.Fname))
Dim finalList = filteredPerson.ToList
For Each p In finalList
    Debug.Print("FNAME: " + p.Fname)
Next

All we want to know is whether Fname is in searchList, which is what Contains does.