LINQ TO SQL Dynamic Queries #3 (And's & Or's Together)

I've received a lot of hits and questions about my first two posts on dynamic queries. If you haven't read them yet I suggest you take a look.

LINQ TO SQL Dynamic Queries (And Operators)
LINQ TO SQL Dynamic Queries (Or Operators)

The reason for today's post is I had a reader ask this question the other day:

"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 "

As it turns out they're right. For some reason this wasn't working correctly. So I fired up LINQPad and started hammering out some queries. It took some time but here is the result of the trial and error session:

VB

Dim basePredicate As Expression(Of Func(Of Student, Boolean)) = PredicateBuilder.True(Of Student)()
basePredicate = basePredicate.And(function(s) false)

for i As Integer = 1 to 10

     Dim predicate1 As Expression(Of Func(Of Student, Boolean)) = _
     PredicateBuilder.True(Of Student)()

     Dim j as Integer = i
     predicate1 = predicate1.And(function(s) s.StudentName.Contains("a"))
     predicate1 = predicate1.And(function(s) s.Grade.Equals(j))
     basePredicate = basePredicate.Or(predicate1)

Next


Dim result As IEnumerable(Of Student) = db.Students.Where(basePredicate)

 

C#

var basePredicate = PredicateBuilder.True<Student>();
basePredicate = basePredicate.And(s => false);

for(int i = 1; i<=10; i++)
{
     var predicate1 = PredicateBuilder.True<Student>();
     int j = i;
     
     predicate1 = predicate1.And(s => s.StudentName.Contains("a"));
     predicate1 = predicate1.And(s => s.Grade == j);
     basePredicate = basePredicate.Or(predicate1);
}

IEnumerable<Student> results = db.Students.Where(basePredicate);

Ok, so a little bit of an explanation is in order.

"basePredicate = basePredicate.And(function(s) false)". I knew that I would have to have a base predicatebuilder (e.g. Dim basePredicate As Expression(Of Func(Of Student, Boolean)) = PredicateBuilder.True(Of Student)())

"basePredicate" is it. Now the weird thing is that if I just create a predicatebuilder WITHOUT assigning the predicate a default value using "basePredicate = basePredicate.And(function(s) false)", it will completely ignore any And or Or statements added to the base predicatebuilder. As a test, leave this line of code out and see what query you get back. It's very interesting. Also, if you use "predicate = predicate.And(function(s) true)" you get a completely different result as well. More to come on that in another post.

"Dim j as Integer = i". If you use "i" in the s.Grade.Equals(i) statement, all of the where statements will have "11" as the value. (e.g. select * from students where (studentname like '%a%' and grade = 11) or (studentname like '%a%' and grade = 11))

I believe this has something to do with the actual query not being completed until the "db.Student.Where(predicate)" statement is called.

Using "s.Grade.Equals(j)" some how magically creates the correct statement. (e.g. select * from students where (studentname like '%a%' and grade = 1) or (studentname like '%a%' and grade = 2))

This doesn't make any sense to me as the integer type is value type. I would understand if it was an reference type but I'm not sure how creating a local integer variable within the loop fixes the issue.

The rest is pretty self-explanatory. You create a new predicate to be used to build the "And" statements.

Dim predicate1 As Expression(Of Func(Of Student), Boolean)) = PredicateBuilder.True(Of Student)()
predicate1 = predicate1.And(function(s) s.StudentName.Contains("a"))
predicate1 = predicate1.And(function(s) s.Grade.Equals(j))

Then we add create the "Or" operators between the And statements by using the base predicatebuilder:

basePredicate = basePredicate.Or(predicate1)

So there you go ilyas, I hope this helps...

posted @ Thursday, April 10, 2008 10:52 AM

Print

Comments on this entry:

# re: LINQ TO SQL Dynamic Queries #3 (And's & Or's Together)

Left by ilyas at 4/10/2008 2:21 PM
Gravatar
Hello chris(You really rock):

After 2 weeks of desperation, finally you solved my problem. I want to thank you a million times for being so sweet of solving my problem, also mailing me(to let me know of this post) and a special thanks for mentioning my name .....
ok lemme thank you a million times like a programmer ;).......

for i as interger 1 to 1000000
response.write(" Thank you chris rocks")
next

I have one more question though haha, hope you didn`t think it was over already.

Here is my question:

In post 2 were you showed OR operator you declare predicate as below
[quote] Dim predicate as Expression(Of Func(Of User, Boolean)) = PredicateBuilder.False(Of User)() [/quote]

In this post, you declare it as:

[quote]Dim predicate1 As Expression(Of Func(Of Student, Boolean)) = _
PredicateBuilder.True(Of Student)()[/quote]

why once predicateBuilder.true and once predicateBuilder.false, i didn`t understand that part...............

Thanks again N Regards,
ilyas

# re: LINQ TO SQL Dynamic Queries #3 (And's & Or's Together)

Left by Paul Fox at 4/15/2008 8:39 AM
Gravatar
Great information... especially the reference to LinqPad of which I did not know existed. A must have app.

For those interested... an example of or's and's with joins;


dim predicate = PredicateBuilder.False(Of vCompetitor)()

predicate = predicate.Or (Function(c) c.EquipmentTypeDesc.Contains("Copier"))
predicate = predicate.Or (Function(c) c.EquipmentTypeDesc.Contains("Fax"))

Predicate = predicate.And (Function(c) c.InsertedByUserName.Contains("Susan"))

dim MyCompetitors = vCompetitor.Where(predicate)

dim MyResult = From SL in vSLMASTMkt Join C in MyCompetitors On SL.AccNoMkt Equals C.AccNo Select SL.AccNoMkt, SL.CoNameMkt, C.InsertedByUserName


Cheers
Paul

# re: LINQ TO SQL Dynamic Queries #3 (And's & Or's Together)

Left by Suresh at 11/14/2008 7:45 PM
Gravatar
i have like N textbox and the id of the textbox is the columname. How can i build the predicate which assigns the column name at runtime.


# sfaxzzxl

Left by sfaxzzxl at 4/9/2009 9:55 AM
Gravatar
sfaxzzxl

# cheap viagra

Left by cheap viagra at 4/11/2009 10:52 AM
Gravatar
cheap viagra

# tlumpikm

Left by tlumpikm at 4/11/2009 6:54 PM
Gravatar
tlumpikm

# jgyigvzr

Left by jgyigvzr at 4/11/2009 6:54 PM
Gravatar
jgyigvzr

# amlodipine

Left by amlodipine at 4/12/2009 1:17 AM
Gravatar
amlodipine

# cheap levitra

Left by cheap levitra at 4/12/2009 1:17 AM
Gravatar
cheap levitra

# cheap viagra

Left by cheap viagra at 4/12/2009 1:17 AM
Gravatar
cheap viagra

# soma

Left by soma at 4/12/2009 1:17 AM
Gravatar
soma

# fosamax

Left by fosamax at 4/12/2009 1:17 AM
Gravatar
fosamax

# purchase soma

Left by purchase soma at 4/12/2009 1:17 AM
Gravatar
purchase soma

# lisinopril

Left by lisinopril at 4/12/2009 3:03 AM
Gravatar
lisinopril

# buy cialis

Left by buy cialis at 4/12/2009 3:03 AM
Gravatar
buy cialis

# naprosyn

Left by naprosyn at 4/12/2009 3:03 AM
Gravatar
naprosyn

# order ambien

Left by order ambien at 4/12/2009 3:03 AM
Gravatar
order ambien

# buy vicodin online

Left by buy vicodin online at 4/12/2009 3:03 AM
Gravatar
buy vicodin online

# adipex online

Left by adipex online at 4/12/2009 3:03 AM
Gravatar
adipex online

# buy tramadol online

Left by buy tramadol online at 4/12/2009 3:04 AM
Gravatar
buy tramadol online

# losec

Left by losec at 4/12/2009 3:04 AM
Gravatar
losec

# propecia online

Left by propecia online at 4/12/2009 3:04 AM
Gravatar
propecia online

# buy valium

Left by buy valium at 4/12/2009 3:04 AM
Gravatar
buy valium

# suntwrdg

Left by suntwrdg at 4/12/2009 9:33 AM
Gravatar
suntwrdg

# hxgxmyom

Left by hxgxmyom at 4/12/2009 9:33 AM
Gravatar
hxgxmyom

# generic zyrtec

Left by generic zyrtec at 4/12/2009 3:11 PM
Gravatar
generic zyrtec

# desyrel

Left by desyrel at 4/12/2009 3:11 PM
Gravatar
desyrel

# propecia

Left by propecia at 4/12/2009 3:11 PM
Gravatar
propecia

# ciprofloxacin

Left by ciprofloxacin at 4/12/2009 3:11 PM
Gravatar
ciprofloxacin

# buy phentermine online

Left by buy phentermine online at 4/12/2009 3:11 PM
Gravatar
buy phentermine online

# buy adipex

Left by buy adipex at 4/12/2009 3:11 PM
Gravatar
buy adipex

# order valium online

Left by order valium online at 4/12/2009 3:11 PM
Gravatar
order valium online

# ynwsbtlu

Left by ynwsbtlu at 4/12/2009 10:27 PM
Gravatar
ynwsbtlu

# cdijfomu

Left by cdijfomu at 4/12/2009 10:27 PM
Gravatar
cdijfomu

# buy carisoprodol online

Left by buy carisoprodol online at 4/13/2009 3:51 PM
Gravatar
buy carisoprodol online

# generic propecia

Left by generic propecia at 4/13/2009 5:09 PM
Gravatar
generic propecia

# fioricet

Left by fioricet at 4/13/2009 5:09 PM
Gravatar
fioricet

# simvastatin

Left by simvastatin at 4/13/2009 6:26 PM
Gravatar
simvastatin

# prilosec

Left by prilosec at 4/13/2009 6:26 PM
Gravatar
prilosec

# buy zoloft

Left by buy zoloft at 4/13/2009 6:26 PM
Gravatar
buy zoloft

# generic cialis

Left by generic cialis at 4/13/2009 6:26 PM
Gravatar
generic cialis

# premarin

Left by premarin at 4/13/2009 6:26 PM
Gravatar
premarin

# vicodin online

Left by vicodin online at 4/13/2009 6:26 PM
Gravatar
vicodin online

# order ultram

Left by order ultram at 4/13/2009 6:26 PM
Gravatar
order ultram

# order adipex

Left by order adipex at 4/13/2009 6:27 PM
Gravatar
order adipex

# phentermine online

Left by phentermine online at 4/13/2009 6:27 PM
Gravatar
phentermine online

# lansoprazole

Left by lansoprazole at 4/13/2009 6:27 PM
Gravatar
lansoprazole

# ztxjwdgk

Left by ztxjwdgk at 4/14/2009 1:57 AM
Gravatar
ztxjwdgk

# yuzqnfne

Left by yuzqnfne at 4/14/2009 1:58 AM
Gravatar
yuzqnfne

# hsjzofur

Left by hsjzofur at 4/14/2009 1:59 AM
Gravatar
hsjzofur

# order carisoprodol online

Left by order carisoprodol online at 4/14/2009 7:09 AM
Gravatar
order carisoprodol online

# generic norvasc

Left by generic norvasc at 4/14/2009 7:09 AM
Gravatar
generic norvasc

# lexapro

Left by lexapro at 4/14/2009 7:09 AM
Gravatar
lexapro

# ambien online

Left by ambien online at 4/14/2009 7:09 AM
Gravatar
ambien online

# generic zocor

Left by generic zocor at 4/14/2009 7:09 AM
Gravatar
generic zocor

# sibutramine

Left by sibutramine at 4/14/2009 7:10 AM
Gravatar
sibutramine

# generic nexium

Left by generic nexium at 4/14/2009 7:10 AM
Gravatar
generic nexium

# attributed solutions roughly

Left by attributed solutions roughly at 5/19/2009 12:30 PM
Gravatar
cosmic safari notes oscillation made uncertain intensity

# re: LINQ TO SQL Dynamic Queries #3 (And's & Or's Together)

Left by imperialx at 12/4/2009 9:02 AM
Gravatar
You saved my life Chris Rock!

Just like the gentlemen above says, "Thanks a million!" well, I'm thanking you a Billion times! ;)

Your comment:



 (will not be displayed)


 
 
 
Please add 3 and 7 and type the answer here:
 

Live Comment Preview:

 
«March»
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910