Как заставить Lambda в LINQ фактически фильтровать динамический linq - PullRequest
0 голосов
/ 10 сентября 2009

Пример - у меня есть человек класса

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

Конечный класс

  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

Это все равно возвращает всех 5 человек, например, где не применяется, что я делаю не так?

Я также хотел бы иметь возможность передать список имен и вернуть только те,

  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 голосов
/ 10 сентября 2009

Проблема в том, что Где не меняет коллекцию. Возвращает вновь отфильтрованную коллекцию.

Попробуйте это:

 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 является указанным именем - и это не будет Боб и Дейв! Я думаю, что вы действительно хотите что-то, что может быть выражено гораздо проще:

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.

0 голосов
/ 10 сентября 2009
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
...