LINQ TO SQL Dynamic Queries #2 (Or statements)

In my last post about LINQ to SQL Dynamic queries I showed you how to create dynamic sql statements with a catch; you would only get AND operators in the WHERE statement of the query. Thanks to LINQ Kits' Predicate Builder, you can now have OR operators as well. However, one of the problems with LINQ Kit is it was created for C# users. Not that there's anything wrong with that. That allows me to write a post explaining how to use it in VB. Thanks LINQ Kit!

The easiest way to show you how to use it is by going back to the example in the first dynamic query post.

Public Function SearchUsers(ByVal firstName As String, ByVal lastName As String) As IEnumerable(Of User)
    Dim db As New MyDataContext
    Dim query As IQueryable(Of User) = db.Users

    If Not String.IsNullOrEmpty(firstName) Then
        query = query.Where(Function(u As User) u.FirstName.Contains(firstName))
    End If

    If Not String.IsNullOrEmpty(lastName) Then
        query = query.Where(Function(u As User) u.LastName.Contains(lastName))
    End If

    Dim result As IEnumerable(Of User) = query.Select(Function(u As User) u)
    
    Return result
End Function
         

Like I said before, this example creates this query:

        SELECT 
            [t0].[UserId], 
            [t0].[FirstName], 
            [t0].[LastName], 
            [t0].[Address], 
            [t0].[Address2], 
            [t0].[City], 
            [t0].[State], 
            [t0].[PostalCode], 
            [t0].[EmailAddress] 
        FROM [dbo].[Users] 
            AS [t0] WHERE ([t0].[LastName] LIKE %rock%) AND ([t0].[FirstName] LIKE %chris%)
        

 Now we want to change the method above to create OR operators. Here is the code:

' need these imports:
Imports LinqKit.Linq
Imports LinqKit
Imports LinqKit.Extensions
Imports System.Linq.Expressions
Imports System.Data.Linq

Public Function SearchUsers(ByVal firstName As String, ByVal lastName As String) As IEnumerable(Of User)
    Dim db As New MyDataContext
    Dim query As IQueryable(Of User) = db.Users
    Dim predicate as Expression(Of Func(Of User, Boolean)) = PredicateBuilder.False(Of User)()

    If Not String.IsNullOrEmpty(firstName) Then
        predicate = predicate.Or(Function(u As User) u.FirstName.Contains(firstName))
    End If

    If Not String.IsNullOrEmpty(lastName) Then
        predicate = predicate.Or(Function(u As User) u.LastName.Contains(lastName))
    End If

    Dim result As IEnumerable(Of User) = db.Users.Where(predicate)
    
    Return result
End Function
         
So what does this code do? Let's go over a few lines from the method above.

Dim predicate as Expression(Of Func(Of User, Boolean)) = PredicateBuilder.False(Of User)()


This is setting up an Expression(Of TDelegate) type from the System.Linq.Expression class. The definition of which is "Represents a strongly typed lambda expression as a data structure in the form of an expression tree. This class cannot be inherited."

O.K., let me TRY to explain that in English. You're creating an Expression that will require a function (or lambda expression) which will be defined as something similar to:

Function MyLamdbaExpression(u As User) As Boolean.

The function (lambda expression) will accept a type of User as the single parameter and return a Boolean value. Hence the "Function(u as User) return u.FirstName.Contains(firstName)" lambda expression. There are a few resources about lambda expressions and generic delegates that I list at the end of the post if you need more help understanding this topic.

The LINQ Kit authors also explain that the true and false methods on the PredicateBuilder class do nothing special: they are convenient shortcuts for creating an Expression(Of Func(Of T, Boolean)) that initially evaluates to true of false. When you're building a predicate by repeatedly stacking and/or conditions, it's useful to have a starting point of either true or false (respectively).
predicate = predicate.Or(Function(u As User) u.FirstName.Contains(firstName))

 

For the purpose of LINQ TO SQL this is adding an OR operator to the query. If only one call is made to the predicate.Or function, LINQ to SQL will create just the WHERE statement. Any subsequent calls will append an "OR" operator to the "WHERE" clause with the appropriate qualifier statement (e.g. where firstname like '%chris%' OR lastname like '%rock%').

Dim result As IEnumerable(Of User) = db.Users.Where(predicate)


This is almost self-explanatory and to keep it simple we are basically passing our expression to the Where method of System.Linq.Queryable type. This will cause LINQ to SQL to build our query with the Or operators. We should come out with a query that looks like this:

        SELECT 
            [t0].[UserId], 
            [t0].[FirstName], 
            [t0].[LastName], 
            [t0].[Address], 
            [t0].[Address2], 
            [t0].[City], 
            [t0].[State], 
            [t0].[PostalCode], 
            [t0].[EmailAddress] 
        FROM [dbo].[Users] 
            AS [t0] WHERE ([t0].[LastName] LIKE %rock%) OR [t0].[FirstName] LIKE %chris%)
        

So there you go. You can create dynamic queries with LINQ that will create AND operators and OR operators.

Update: LINQ TO SQL Dynamic Queries (And's & Or's)

Here are the resources I promised you.

Technorati Tags: ,,.NET 3.5

posted @ Wednesday, February 27, 2008 11:25 AM

Print

Comments on this entry:

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by ilyas at 4/7/2008 4:35 PM
Gravatar
Hello sir,

I am trying to write the code you provided above to make a dynamic query which will do search using a ListItem.
The problem or error am getting is as below

In the line [quote]Dim result As IEnumerable(Of User) = db.Users.Where(predicate)[/quote]

Error:
[quote]
'System.Collections.IEnumerable' has no type parameters and so cannot have type arguments.
[/quote]........

I also want to use And and Or operators in same query, please tell me how i can do that.......

Thanks and Regards,
ilyas

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by ilyas at 4/9/2008 10:21 AM
Gravatar
Hello Sir,

Thank you for writing such a great post in your site and replying me with answer for my first problem. But i didn't get any answer for my next question, how can i have both AND operator and OR operator in one Dynamic query.

Example:
student table:
id int
name varchar(10)
grade int

i want to write a query like below:

select * from student where ((name LIKE "%a%") AND (grade = '1')) OR ((name LIKE "%a%") AND (grade = '2')) OR ...... OR ((name LIKE "%a%") AND (class = '10'));

I tried to build something like below by seeing your post in your site:

For i As Integer = 1 To 10
predicate = predicate.AND(Function(p As STUDENT) p.name.Contains("a"))
predicate = predicate.OR(Function(p As STUDENT) p.class = i )
Next

Dim result As IEnumerable(Of STUDENT) = db.STUDENTs.Where(predicate)

But the Predicate.AND seems to be not working the debugger is avoiding it, sir can you please solve my problem......

Sitting on the edge of my seat and waiting for your early response........

Thanks and Regards,
ilyas

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by amir at 2/28/2009 5:38 AM
Gravatar
I am having a problem with generated SQL.


if i have varchar and text and i get the following SQL.

....AS [t0] WHERE ([t0].[Title] LIKE '%rock%') AND ([t0].[Contents] LIKE %chris%)

Notice the "Contents" field which is "TEXT" file has quotes remove whereas Title field which is VARCHAR has proper quotes. This is causing SQL to generate error message.

please help and if possible reply to my email address.

thanks in advance.

amir

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by amir at 2/28/2009 5:47 AM
Gravatar
I am having a problem with generated SQL.


if i have varchar and text and i get the following SQL.

....AS [t0] WHERE ([t0].[Title] LIKE '%rock%') AND ([t0].[Contents] LIKE %chris%)

Notice the "Contents" field which is "TEXT" file has quotes remove whereas Title field which is VARCHAR has proper quotes. This is causing SQL to generate error message.

please help and if possible reply to my email address.

thanks in advance.

amir

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by D at 6/23/2009 4:23 PM
Gravatar
could you translate the VB into C#

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by syed aown at 7/5/2009 6:46 AM
Gravatar
Hi,
I ran into a problem whilst applying your logic with my code...i have 2 tables rather than one and i want to build a dynamic where clause as you are doing above but some of my columns are in table1 and some are in table2....in this case how can i achieve the goal...help needed!!!........thanks

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Arun at 7/6/2009 3:21 PM
Gravatar
Can you please send me the Predicate Builder code in VB.net. Earliest reply is highly appericated..
Thanks a lot.

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Imperialx at 12/6/2009 7:41 AM
Gravatar
Hello Chris,

Is this possible on two or more tables using Joins?


-imperialx

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Texas Hold'em poker at 12/12/2009 6:19 AM
Gravatar
For some reason I can’t get this to compile. Could you tell me what DLL references and namespaces I should be using? I think i may be missing one but can’t seem to figure out which one.

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Shared Web Hosting at 12/22/2009 2:26 AM
Gravatar
Good shoot

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Web design studio at 12/30/2009 3:56 PM
Gravatar
Great stuff. Thanks!

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by website design los angeles at 1/4/2010 9:04 AM
Gravatar
Having read nearly all the blog, I have recognized that being a part of online community gives you an awesome chance to gain more knowledge in different spheres.

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Love poetry at 2/4/2010 11:41 AM
Gravatar
Sitting on the edge of my seat and waiting for your early response..

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by mothers day gifts at 2/27/2010 5:38 AM
Gravatar
Shared knowledge gives you satisfaction from within. This may sound too hitech but my sincerity of getting to know more about LINQ starts here.

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Link Building Service at 3/1/2010 3:49 AM
Gravatar
great share thanks for this

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Kishore at 3/2/2010 6:15 AM
Gravatar
Hi,
Nice article.
I have a quick question

Dim result As IEnumerable(Of User) = query.Select(Function(u As User) u)
Return result

All good with this. But what if i want to select foreign key values as well like
Function(u As User) u.username, u.departments.department_name

How to do it?

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by Kishore at 3/2/2010 6:15 AM
Gravatar
Hi,
Nice article.
I have a quick question

Dim result As IEnumerable(Of User) = query.Select(Function(u As User) u)
Return result

All good with this. But what if i want to select foreign key values as well like
Function(u As User) u.username, u.departments.department_name

How to do it?

# re: LINQ TO SQL Dynamic Queries #2 (Or statements)

Left by mydani at 3/11/2010 1:34 PM
Gravatar
Hello,

thanks for the idea - even though I discovered a way using a lambda expression itself which is rather easy to understand:

.Where(x => {
var result = true;
if (Object1.Property1 == specialValue)
result = false;
...
return result;
})

regards,
mydani

Your comment:



 (will not be displayed)


 
 
 
Please add 8 and 3 and type the answer here:
 

Live Comment Preview:

 
«March»
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910