Print Page | Close Window

Or between Where operators

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=2237
Printed Date: 11-Oct-2025 at 5:29pm


Topic: Or between Where operators
Posted By: danjal
Subject: Or between Where operators
Date Posted: 19-Oct-2010 at 9:18am

If I would run a query like this:

 
var query = p_manager.EntTsSet

.Where(ts => ts.p_tsID == 10)

       .Where(ts => ts.p_tsID == 20);

Query((IEntityQuery<EntTs>)query, callback);

 

it would return empty because there is an AND between the two Where operators – so an ID cannot be 10 and 20 at the same time.

 
But what if I want an OR between the two Where operators?

Can I make my own OrWhere operator?

And does anyone know how to do that?




Replies:
Posted By: sbelini
Date Posted: 19-Oct-2010 at 10:23am
danjal,
 
The second Where is filtering the result set of the first Where (just like AND, but not actually AND).
 
You will need both statements within one Where:
 
var query = p_manager.EntTsSet

.Where(ts => ts.p_tsID == 10

        || ts.p_tsID == 20);

Query((IEntityQuery<EntTs>)query, callback);

 



Posted By: danjal
Date Posted: 20-Oct-2010 at 2:02am

Sbelini,

 

I know. But what I want, is to build my query dynamically – something like this:

 

var query = p_manager.EntTsSet;

if (Something)

query = query.Where(ts => ts.p_tsID == 10);

if (SomethingElse)

query = query.Where(ts => ts.p_tsID == 20);

 

query = query.OrderBy(ts => ts.p_tsID);

 

Query((IEntityQuery<EntTs>)query, callback);

 

This is just a simple example. I want to be able to construct more complex queries dynamically, based on that a user enters in a search dialog.



Posted By: sbelini
Date Posted: 20-Oct-2010 at 9:37am
In this case you can use PredicateDescription:
 
   var expr1 = PredicateBuilder.Make(typeof(EntsSet), "p_tsID", FilterOperator.IsEqualTo, 10);
   var expr2 = PredicateBuilder.Make(typeof(EntsSet), "p_tsID", FilterOperator.IsEqualTo, 20);
   var expr1_2 = expr1.Or(expr2);
   var query = PredicateBuilder.FilterQuery(em.EntsSet, expr1_2);
 
You can find detailed information about PredicateDescription in our http://drc.ideablade.com/ApiDocumentation/ - DevForce API Documentation .
 
 
 


Posted By: danjal
Date Posted: 20-Oct-2010 at 9:54am

Thanx sbelini!

 

Looks interesting! I will look into this.

 

 

Here is what I am working on at the moment:

 

The user can search for some items by typing some intervals of ids in a search dialog.

The user would for example type this: 10-20,40-45,100-110

Meaning that the user wants to see the items whose ids range from 10 to 20 and 40 to 45 and 100 to 110.

I would make my query dynamically like this, because I do not know how many intervals the user is going to type into the search dialog:

 

IQueryable<EntTs> query = p_manager.EntTsSet;

 

var strings = param.Split(',');

foreach (string s in strings)

{

var intervals = s.Split('-');

       query = query.Where(ts => ts.p_tsID >= Int32.Parse(intervals[0].Trim()) && ts.p_tsID <= Int32.Parse(intervals[1].Trim()));

}

 

query = query.OrderBy(ts => ts.p_tsID);

Query((IEntityQuery<EntTs>) query, callback);

 

But this does not work because this returns only 100 to 110. But if the Where operators had an Or between them I would get the union, which is that I want.



Posted By: sbelini
Date Posted: 20-Oct-2010 at 11:28am
The PredicateBuilder will also help you in the task you are working on now (the snippet below might help you get started):
 
  List<CompositePredicateDescription> CompPredDescs = new List<CompositePredicateDescription>();
  var strings = param.Split(',');
 
  foreach (string s in strings) {
    var intervals = s.Split('-');
    var expr1 = PredicateBuilder.Make(typeof(Employee), "EmployeeID"
      , FilterOperator.IsGreaterThanOrEqualTo
      , Int32.Parse(intervals[0].Trim()));
    var expr2 = PredicateBuilder.Make(typeof(Employee), "EmployeeID"
      , FilterOperator.IsLessThanOrEqualTo
      , Int32.Parse(intervals[1].Trim()));
    var expr12 = expr1.And(expr2);
    CompPredDescs.Add(expr12);
  }
  if (CompPredDescs.Count > 0) {
    var expr = CompPredDescs[0];
    for (int i = 1; i < CompPredDescs.Count; i++) {
      expr = expr.Or(CompPredDescs);
    }
    var exprFunc = (Expression<Func<Employee, bool>>)expr.ToLambdaExpression();
    var query = mgr.Employees.Where(exprFunc);
    var results = query.Execute();
  }
}
 
 
I hope it helps
 


Posted By: danjal
Date Posted: 21-Oct-2010 at 3:32am

Thanx again sbelini!

This PredicateBuilder is excellent!

This is exactly what I was looking for!

Here is what my query ends up looking like:

 

var predicate = PredicateBuilder.True<EntTs>();

var strings = param.p_text.Split(',');

foreach (string s in strings)

{

var intervals = s.Split('-');

       predicate = predicate.Or(ts => ts.p_tsID >= Int32.Parse(intervals[0].Trim()) && ts.p_tsID <= Int32.Parse(intervals[1].Trim()));

}

var query = p_manager.EntTsSet.Where(predicate);

query = query.OrderBy(ts => ts.p_tsID);

Query(query,callback);

 

 

And if I use the help from my JetBrains Reshaper, it ends up looking like this:

 

var predicate = PredicateBuilder.True<EntTs>();

var strings = param.p_text.Split(',');

predicate = strings.Select(s => s.Split('-')).Aggregate(predicate, (current, intervals) => current.Or(ts => ts.p_tsID >= Int32.Parse(intervals[0].Trim()) && ts.p_tsID <= Int32.Parse(intervals[1].Trim())));

var query = p_manager.EntTsSet.Where(predicate);

query = query.OrderBy(ts => ts.p_tsID);

Query(query,callback);

 

 

Just love it!




Print Page | Close Window