New Posts New Posts RSS Feed: Limitations with predicates?
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Limitations with predicates?

 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: Limitations with predicates?
    Posted: 29-Dec-2011 at 8:08am

We are using newest version 6.1.4

In one of our queries, we use a predicate like this:

 

var ids = someIds as List<int>;

 

var predicate = PredicateBuilder.False<EntAlarm>();

 

if (ids.Count > 0)

predicate = ids.Aggregate(predicate,

                           (current, id) =>

                           current.Or(a => a.p_alarmID == id));

 

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

 

query.QueryStrategy = new QueryStrategy(FetchStrategy.DataSourceThenCache, MergeStrategy.PreserveChanges);

 

Query(query, callback);

 

 

If the list of someIds gets big (2000 ids), we get a stackoverflow error in IdeaBlade.Linq.dll.

Are there some limits, when working with predicates?

 



Edited by danjal - 29-Dec-2011 at 8:10am
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 29-Dec-2011 at 8:01pm
Hi danjal;

DevForce IdeaBlade.Linq is built on top of System.Linq. DevForce itself doesn't set any limit when working with predicates. It's possible that this stack overflow is a .NET limitation itself when building large expression trees. I'm able to reproduce this issue here. Let me investigate this further and I'll get back to you as soon as possible.
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: 02-Jan-2012 at 3:52am

I find that when using the predicate builder - the queries become slow, but this is perhaps expected?

 

Now I have discovered ESQL – so I tried it instead like this:

 

var ids = alarmIds as List<int>;

 

var q = new PassthruEsqlQuery(typeof (EntAlarm),

"SELECT VALUE A from EntAlarms as A where A.p_alarmID in {" + String.Join(",",ids.Select(id => id.ToString()).ToArray()) + "}");

 

q.With(p_manager).ExecuteAsync(results => test(results, callback));

 

I think it is faster.

But if the list of ids gets too big, I get this error:

 

{EntityServerException: The query syntax is not valid. Near term '}', line 1, column 59. ---> System.Data.EntitySqlException: The query syntax is not valid. Near term '}', line 1, column 59.

   at IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor.HandleException(Exception e, PersistenceFailure failureType)...

UPDATED: I got a syntax error when using ESQL, because in one case the the list of ids was empty. I discovered this by looking in the debug log:
Fetch ... PassthruEsqlQuery: [EntAlarm] Esql: SELECT VALUE A from EntAlarms as A where A.p_alarmID in {}

 
One question about ESQL: Is it not possible use .Include() or do I have to lazy load the related entities?
 


Edited by danjal - 02-Jan-2012 at 7:51am
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 03-Jan-2012 at 1:21pm
Hi Danjal;

My suspicion is correct. The StackOverflowException occurs because the predicate will contain a very large OR clause as the expression contains a large list of ids. The exception occurs as we recursively visit the large expression tree.

The workaround for this is to use the the FilterOperator.InList operator or .Contains. See example below.

var ids = new List<int>();
for (int i = 0; i < 2000; i++) {
  ids.Add(i);
}
var pd = new PredicateDescription("Id", FilterOperator.InList, ids);
var query = mgr.Products.Where(pd);
var query2 = mgr.Products.Where(p => ids.Contains(p.Id));
var list = query.ToList();

Re: your question on Esql, unfortunately it's not possible to use .Include() with PassThruEsqlQuery.

Hope this helps.
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: 04-Jan-2012 at 2:28am
Hi DenisK,
 
Thanks, these are good alternativs.
 
We would have liked to see more options with PassThruEsqlQuery.
 
Do you know if there are any performance differences between PassThruEsqlQuery and the regular EntityQuery?
 
 
Regards
Danjal


Edited by danjal - 04-Jan-2012 at 2:28am
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 04-Jan-2012 at 5:30pm
PassThruEsqlQuery is a data source only query so you lose the benefits of caching there. However, I would say that in general Esql query is faster since the expression composed is less complex and so there's less processing involved.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down