Print Page | Close Window

Limitations with predicates?

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=3185
Printed Date: 13-May-2026 at 3:08pm


Topic: Limitations with predicates?
Posted By: danjal
Subject: Limitations with predicates?
Date 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?

 




Replies:
Posted By: DenisK
Date 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.


Posted By: danjal
Date 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?
 


Posted By: DenisK
Date 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.


Posted By: danjal
Date 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


Posted By: DenisK
Date 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.



Print Page | Close Window