Click here to Skip to main content
16,004,647 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All,

I have a generic list which contains around 250 results. These results are the collection of some class. That class contains properties like Title, Keyword and etc. Now on this generic list I want to find out the results with "Exact match", "All words match" and "One or more word match". For example, in result set some results have Title containing values as "test linq sample", "linq sample", "sample test linq" , "sample test" and etc. Now I want to apply a filter on this list by using LINQ with VB.NET. Let say, my search term is "sample test linq" and in return I need results on following

1) Results for EXACT match. That is, those result where Title contains "sample test linq"
2) Result for ALL word Match. That is, those results where Title contains all the words from "sample test linq" (By using AND condition in LINQ query)
3) Result for One or more word Match. That is, those results where Title contains any of the word present in title (By using OR condition in LINQ query)

Can some one has any idea how to achieve this by using LINQ with VB.NET code. Here my search term gets changed i.e it contains one or more words. For this I need to dynamically create WHERE clause of LINQ at runtime, by writing the logic in some function.

Dim query = From result in listResultSet
Where "Conditions"

I have goggled a lot on this but what I am getting is below two links and the code that is related to C#. What I need is VB.NET code

http://www.albahari.com/nutshell/predicatebuilder.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Thanks
Posted
Comments
joshrduncan2012 29-Oct-13 10:23am    
Have you tried finding something that can convert the C# code you find to its equivalent VB.NET?
Daljeet S Saluja 29-Oct-13 10:36am    
Yes, I have tried to convert C# code provided in below two links
http://www.albahari.com/nutshell/predicatebuilder.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

But that did not solve my problem

You said
I have a generic list which contains around 250 results.
This implies that you are using LINQ to Objects, so you don't seem to need to construct a query that will be "sent off" to a SQL server to execute for efficiency. The query will execute in your code. (And a collection of 250 items is not a large collection.)
I'd probably just choose between 3 different queries for the 3 cases.
It is going to be more efficient than dynamically constructing the queries, and almost certainly a whole lot easier to implement and maintain.
 
Share this answer
 
The "Where" clause requires a boolean value. You can supply that with a function. Here is an example based on my understanding of your issue. You can feed that function whatever arguments you need to generate your "dynamic Where" clause.

Private Sub Test()
   Dim items As New List(Of Item)
   items.Add(New Item("this is a test"))
   items.Add(New Item("this is not a test"))
   items.Add(New Item("this is maybe a test"))
   items.Add(New Item("something else"))
   items.Add(New Item("something else test"))

   Dim lookfor As String = "this is a test"

   Console.WriteLine("Exact Match: " & lookfor)
   For Each itm As Item In GetMatchedItems(items, lookfor, MatchType.Exact)
      Console.WriteLine(itm.Title)
   Next itm

   Console.WriteLine("----------------------")
   Console.WriteLine("Contains all: " & lookfor)
   For Each itm As Item In GetMatchedItems(items, lookfor, MatchType.ContainsAll)
      Console.WriteLine(itm.Title)
   Next itm

   Console.WriteLine("----------------------")
   lookfor = "else not"
   Console.WriteLine("Contains one or more: " & lookfor)
   For Each itm As Item In GetMatchedItems(items, lookfor, MatchType.ContainsOneOrMore)
      Console.WriteLine(itm.Title)
   Next itm
End Sub

Private Function GetMatchedItems(ByVal source As List(Of Item), ByVal lookfor As String, ByVal mt As MatchType) As IEnumerable(Of Item)
   Return From el In source _
          Let itm As Item = DirectCast(el, Item) _
          Where MatchTester(itm.Title, lookfor, mt) _
          Select itm
End Function

Private Function MatchTester(ByVal teststring As String, ByVal lookfor As String, ByVal match As MatchType) As Boolean
   If Not [Enum].IsDefined(GetType(MatchType), match) Then
      Throw New ArgumentException("Invalid MatchType")
   End If

   Select Case match
      Case MatchType.Exact
         MatchTester = String.Equals(teststring, lookfor)

      Case MatchType.ContainsAll, MatchType.ContainsOneOrMore
         Dim source As New List(Of String)(teststring.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries))
         Dim findthese As New List(Of String)(lookfor.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries))

         If match = MatchType.ContainsAll Then
            MatchTester = True
            For Each word As String In findthese
               If Not source.Contains(word) Then
                  MatchTester = False
                  Exit For
               End If
            Next word
         Else
            MatchTester = False
            For Each word As String In findthese
               If source.Contains(word) Then
                  MatchTester = True
                  Exit For
               End If
            Next
         End If
   End Select
End Function

Private Enum MatchType
   Exact
   ContainsAll
   ContainsOneOrMore
End Enum 'MatchType

Private Class Item
   Public Sub New(ByVal Title As String)
      Me._Title = Title
   End Sub

   Private _Title As String
   Public Property Title() As String
      Get
         Return _Title
      End Get
      Set(ByVal value As String)
         _Title = value
      End Set
   End Property 'Title
End Class ' Item
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900