vb.netlistobject

VB.Net : how to search in a list of objects with a string parameter?


My code is in VB.NET but I understand C# if you have the solution.

I have a list<myObj> that I fill if I don't find value.

To avoid duplicates, I have some validation first.

Here's the example:

' My vl_myObj is already filled

Dim vListeAjout As New List(Of myObj)

For each Item_myObj As myObj In vl_myObj
    Dim StringFind as string = ""

    If MyCurrentRecord.Kind <> "M" And MyCurrentRecord.Kind <> "P" Then
       StringFind += " And c.LienPartie = " & Item_myObj.LienPartie 
    End If
    If MyCurrentRecord.Kind = "O" Then
       StringFind += " And c.Equipe= " & Item_myObj.Equipe
    End If
    
    ' I have some other IF ...

    ' At the end of these IF, I remove the first " AND" to start correctly
    StringFind = StringFind.Substring(4)

    ' If I had written my research directly, it would have worked

    ' Dim tryFindItem = vListeAjout.Find(Function(c) c.LienPartie = 11575 And c.Equipe = 11)

What I want (and try) is:

     Dim tryFindItem = vListeAjout.Find(Function(c) StringFind)

If the list is empty, it's OK, but when I try when the list contains one element, I get this error:

An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll

Additional information: Conversion from string " c.LienPartie = 11575 And c.Equi" to type 'Boolean' is not valid.


Solution

  • You cannot use a condition given as string in the Find() function. But you can compose a condition by appending LINQ Where caluses to a query like this:

    ' vl_myObj is already filled
    Dim vListeAjout As New List(Of myObj)
    
    Dim query As IEnumerable(Of myObj) = vListeAjout
    For Each Item_myObj As myObj In vl_myObj
        If MyCurrentRecord.Kind <> "M" And MyCurrentRecord.Kind <> "P" Then
            query = query.Where(Function(c) c.LienPartie = Item_myObj.LienPartie)
        End If
        If MyCurrentRecord.Kind = "O" Then
            query = query.Where(Function(c) c.Equipe = Item_myObj.Equipe)
        End If
    
        ' Some other If ...
    
        Dim tryFindItem = query.FirstOrDefault()
        If tryFindItem IsNot Nothing Then
            ' Do something with tryFindItem
        End If
    Next
    

    Note that the query will only be executed when calling FirstOrDefault(), so during the composition the list will not be iterated.