15

Closed

Native support for Enumerable.Contains

description

Currently Enumerable.Contains like this:

new [1,2,3].Contains(a)

Is translated to an sub-tree of expressions equivalent to

1 == a || 2 == a || 3 == a

This expression tree is kept balanced to avoid stack overflows in our visitor code and finally translated to an IN expression in SQL-gen:

a IN (1,2,3)

We do a lot of in-memory processing to do both translations and the numbers of elements in the list has been reported to have exponential impact on the performance of query translation:

http://stackoverflow.com/questions/7897630/why-does-the-contains-operator-degrade-entity-frameworks-performance-so-drama/7936350#7936350

We can avoid the whole issue if we add support for a DbExpression that can hold a collection parameter directly and also have IN/Contains semantics. The addition of this expression would imply a change to the provider model, but the benefits would be huge for this kind of query when there are many elements.

Alternatively we could profile the processing that we do in this case and see if there is any low hanging optimization we can still do in the code.
Closed Jan 7 at 3:26 PM by BriceLambson

comments

Dave69B wrote Oct 5, 2012 at 10:13 AM

I've just encountered this. My users have access to depots. In views screens they can filter by any selected subset of these. On a clients site where a user has access to 100 it takes 4 seconds to build the query and 0.1 to execute it. e.g
var query = from fb in FITTERBOOKINGS
where fb.BOOKINGDATE == theDate && fb.DRIVER != string.Empty
&& selectedDepotList.Contains(fb.DRIVERS.DEPOT)
select fb;

My screen full refresh time exploded from 1 second to 12 as there are 4 queries that must run. I must admit I did not check for support of a SQL IN when comparing EF against other options.

Please, please, please add support for array.Contains as a SQL in before the boss forces me to take EF out.

fujiy wrote Dec 6, 2012 at 4:47 PM