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.
Comments: Hi, I am working in the implementation of DbInExpression support in MySql Connector/NET the problem is that the call to Visit(DbInExpression) is never made in the following query sample: List<int> Ages = new List<int>(); Ages.AddRange(new int[] { 37, 38, 39, 40, 41, 42, 43 }); var q = from e in context.Employees where Ages.Contains(e.Age.Value) orderby e.LastName, e.FirstName select e; string[,] data1 = new string[,] { { "Flintstone", "Fred" }, { "Flintstone", "Wilma" }, { "Rubble", "Barney" } }; string query; query = q.ToTraceString(); foreach (var e in q) { ... } So, my question is, for other database providers is there supposed to be something else beyond implementing Visit( DbInExpression ) in our implementation of DbExpressionVisitor? Thanks.
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.
Comments: Hi, I am working in the implementation of DbInExpression support in MySql Connector/NET the problem is that the call to Visit(DbInExpression) is never made in the following query sample: List<int> Ages = new List<int>(); Ages.AddRange(new int[] { 37, 38, 39, 40, 41, 42, 43 }); var q = from e in context.Employees where Ages.Contains(e.Age.Value) orderby e.LastName, e.FirstName select e; string[,] data1 = new string[,] { { "Flintstone", "Fred" }, { "Flintstone", "Wilma" }, { "Rubble", "Barney" } }; string query; query = q.ToTraceString(); foreach (var e in q) { ... } So, my question is, for other database providers is there supposed to be something else beyond implementing Visit( DbInExpression ) in our implementation of DbExpressionVisitor? Thanks.