views:

222

answers:

2

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

Regards

_Eric

+2  A: 

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.

Jon Skeet
Eric
That's it! That's exactly what I was trying to convey. Thanks
Eric
@Jon: I don't know the syntax. Could you give an example for 2nd case with a JOIN instead?
shahkalpesh
@shahkalpesh: I have no idea what you mean, I'm afraid. Which second case, and why would you want a join?
Jon Skeet
@Jon: Please see the example code below.
shahkalpesh
+1 for Contains. People really struggle with that. I believe that it's because you are doing the operation on the second data set and using the first element as the parameter, whereas the procedural approach is to think 'for each element in my search list'...
Kirk Broadhurst
A: 
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 searchList As New List(Of String)
searchList.Add("Bob")
searchList.Add("Dave")

dim filteredItems = from p in people _
join i in searchList on p.FName equals i _
select p

dim personFound as Person

for each personFound in filteredItems
    Console.WriteLine(personFound.Lname)
next
shahkalpesh