How to get Lambda in LINQ to actually filter for dynamic linq

Asked
Viewd1360

0

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

2 个答案

2

问题在于,在哪里不更改集合。它返回新过滤的集合。

尝试一下:

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

(顺便说一句,我在这里看不到任何动态的东西...您在哪里使用动态LINQ?)

要添加多个Where子句,您将需要以下内容:

 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
 

但是,我不认为这实际上是您想要执行的操作。每个Where子句都将坚持Fname是指定的名称-而不是Bob Dave!我认为您实际上想要可以更简单地表达的内容:

 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
 

我们只想知道Fname是否在searchList中,这就是Contains的作用。

  • +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 BroadhurstNovember 23, 2009 11:36
  • @shahkalpesh: I have no idea what you mean, I’m afraid. Which second case, and why would you want a join?

    Jon SkeetSeptember 10, 2009 16:58
  • @Jon: I don’t know the syntax. Could you give an example for 2nd case with a JOIN instead?

    shahkalpeshSeptember 10, 2009 16:55
  • It is in the last code section, where I want to be able to pass in a list of names adding where clauses for each name, in that example I would expect a list(of Person) with 2 items Bob & Dave

    EricSeptember 10, 2009 16:51
  • That’s it! That’s exactly what I was trying to convey. Thanks

    EricSeptember 10, 2009 16:55
0
 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