New Posts New Posts RSS Feed: Or between Where operators
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Or between Where operators

 Post Reply Post Reply
Author
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post Topic: Or between Where operators
    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?

Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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);

 

Back to Top
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post 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.

Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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 DevForce API Documentation.
 
 
 
Back to Top
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post 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.

Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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
 


Edited by sbelini - 20-Oct-2010 at 11:29am
Back to Top
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post 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!

Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down