Dynamically building Predicate description
Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2037
Printed Date: 10-Jun-2026 at 5:03pm
Topic: Dynamically building Predicate description
Posted By: BillG
Subject: Dynamically building Predicate description
Date Posted: 30-Jul-2010 at 3:38pm
|
I have a search form that has 5 fields on it; ssn, cardno,employeeno, firstname, lastname. The user could fill in anyone of the fields and click find to find the member.
I am collecting the filled-in fields with a Query Object and passing it to my FetchMembers() method in my viewmodel.
Here is the code so far.
PredicateDescription p1 = null;
PredicateDescription p2 = null;
PredicateDescription p3 = null;
PredicateDescription p4 = null;
PredicateDescription p5 = null;
if(q.SSN != string.Empty)
p1 = PredicateBuilder.Make(typeof(Member), "SocSecNo", FilterOperator.IsEqualTo, q.SSN);
if(q.LastName != string.Empty)
p2 = PredicateBuilder.Make(typeof(Member), "LastName", FilterOperator.StartsWith, q.LastName);
if(q.FirstName != string.Empty)
p3 = PredicateBuilder.Make(typeof(Member), "FirstName", FilterOperator.StartsWith, q.FirstName);
if(q.EmployeeNo != string.Empty)
p4 = PredicateBuilder.Make(typeof(Member), "EmployeeNo", FilterOperator.IsEqualTo, q.EmployeeNo);
if(q.CardNo != 0)
p5 = PredicateBuilder.Make(typeof(Member), "CardNo", FilterOperator.IsEqualTo, q.CardNo);
var query = PredicateBuilder.FilterQuery(entityManager.Members, p1.And(p2).And(p3).And(p4).And(p5));
but not all the PredicateDescription objects might have values. How do I dynamically combine the p1, p2, p3 only if they are not null.
Bill
|
Replies:
Posted By: GregD
Date Posted: 02-Aug-2010 at 11:52am
There is a static overload on PredicateBuilder
public static Expression<Func<T, Boolean>> And<T>(params Expression<Func<T, Boolean>>[] expressions) { |
that allows an arbitrary array of Expression<…> to be anded together. So code would look something like…
List<Expression<Func<Member, bool>> expressions = new List<Func<Member, bool>>();
if(q.SSN != string.Empty)
expressions.Add(PredicateBuilder.Make(typeof(Member), "SocSecNo", FilterOperator.IsEqualTo, q.SSN));
if(q.LastName != string.Empty)
expressions.Add(PredicateBuilder.Make(typeof(Member), "LastName", FilterOperator.StartsWith, q.LastName));
if(q.FirstName != string.Empty)
expressions.Add(PredicateBuilder.Make(typeof(Member), "FirstName", FilterOperator.StartsWith, q.FirstName));
var newExpr = PredicateBuilder.And(expressions.ToArray());
var query = PredicateBuilder.FilterQuery(entityManager.Members, newExpr); |
|
Posted By: BillG
Date Posted: 03-Aug-2010 at 1:18pm
|
Here is the new revised method but I am getting a syntax error after the comma in the word Member
public void FetchMembers(MemberQuery q)
{
List<Expression< Func<Member, bool>> expressions = new List<Func<Member, bool>>(); //Error on this line.
if(q.SSN != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "SocSecNo", FilterOperator.IsEqualTo, q.SSN));
if(q.CardNo != 0)
expressions.Add( PredicateBuilder.Make(typeof(Member), "CardNo", FilterOperator.IsEqualTo, q.CardNo));
if(q.EmployeeNo != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "EmployeeNo", FilterOperator.IsEqualTo, q.EmployeeNo));
if(q.LastName != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "LastName", FilterOperator.IsEqualTo, q.LastName));
if(q.FirstName != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "FirstName", FilterOperator.IsEqualTo, q.FirstName));
var newExpr = PredicateBuilder.And(expressions.ToArray());
var query = PredicateBuilder.FilterQuery(entityManager.Members, newExpr);
var results = query.Execute<Member>();
results.ForEach(Members.Add);
}
|
Posted By: BillG
Date Posted: 03-Aug-2010 at 1:23pm
|
Ok I found the problem it was missing a > in the first line but where is the Expression class located?
Bill
|
Posted By: BillG
Date Posted: 03-Aug-2010 at 1:58pm
|
Make a little bit more progress, Expression is in System.Linq.Expressions. here is the updated code so far
public void FetchMembers(MemberQuery q)
{
List<Expression<Func<Member, bool>>> expressions = new List<Expression<Func<Member, bool>>>();
if(q.SSN != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "SocSecNo", FilterOperator.IsEqualTo, q.SSN));
if(q.CardNo != 0)
expressions.Add( PredicateBuilder.Make(typeof(Member), "CardNo", FilterOperator.IsEqualTo, q.CardNo));
if(q.EmployeeNo != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "EmployeeNo", FilterOperator.IsEqualTo, q.EmployeeNo));
if(q.LastName != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "LastName", FilterOperator.IsEqualTo, q.LastName));
if(q.FirstName != string.Empty)
expressions.Add( PredicateBuilder.Make(typeof(Member), "FirstName", FilterOperator.IsEqualTo, q.FirstName));
var newExpr = PredicateBuilder.And(expressions.ToArray());
var query = PredicateBuilder.FilterQuery(entityManager.Members, newExpr);
var results = query.Execute<Member>();
results.ForEach(Members.Add);
}
I am getting two made errors they prefer to each add line.
Error 1 The best overloaded method match for 'System.Collections.Generic.List<System.Linq.Expressions.Expression<System.Func<DomainModel.Member,bool>>>.Add(System.Linq.Expressions.Expression<System.Func<DomainModel.Member,bool>>)' has some invalid arguments D:\Software Development\VS2010\TicketWare2010\TicketWare2010\Models\MemberViewModel.cs 67 18 TicketWare2010
Error 2 Argument 1: cannot convert from 'IdeaBlade.Linq.PredicateDescription' to 'System.Linq.Expressions.Expression<System.Func<DomainModel.Member,bool>>' D:\Software Development\VS2010\TicketWare2010\TicketWare2010\Models\MemberViewModel.cs 67 34 TicketWare2010
|
Posted By: BillG
Date Posted: 04-Aug-2010 at 3:09pm
Posted By: GregD
Date Posted: 24-Aug-2010 at 6:00pm
|
Bill:
Thanks for backchannelling the AdventureworksDB-backed sample. That made it a lot easier to understand and address your question.
Here's a version of your FetchCustomers() method that compiles:
public void FetchCustomers(CustomerQueryObject q) { List<PredicateDescription> predicateDescriptions = new List<PredicateDescription>();
PredicateDescription aPredicateDescription; if (q.CompanyName != string.Empty) { aPredicateDescription = PredicateBuilder.Make(typeof(Customer), "CompanyName", FilterOperator.IsEqualTo, q.CompanyName); predicateDescriptions.Add(aPredicateDescription); }
if (q.LastName != string.Empty) predicateDescriptions.Add(PredicateBuilder.Make(typeof(Customer), "LastName", FilterOperator.IsEqualTo, q.LastName));
if (q.FirstName != string.Empty) predicateDescriptions.Add(PredicateBuilder.Make(typeof(Customer), "FirstName", FilterOperator.IsEqualTo, q.FirstName));
CompositePredicateDescription aCompositePredicateDescription = PredicateBuilder.And(predicateDescriptions.ToArray()); IQueryable query = PredicateBuilder.FilterQuery(mgr.Customers, aCompositePredicateDescription);
IEnumerable results = mgr.ExecuteQuery((IEntityQuery)query);
foreach (Customer aCustomer in results) { Customers.Add(aCustomer); }
} |
|
|