Является ли пространство имен Expression.* единственным способом создания деревьев выражений для EF 4.3 + ODAC?

У меня проблема с ODAC (компоненты доступа к данным Oracle), Entity Framework 4.3.1 и деревьями выражений. У нас есть устаревшая база данных (не так ли?), которую мы отображаем в Entity Framework. В таблице миллионы записей и более сотни столбцов (грустное лицо).

Вот пример запроса для индексированного столбца:

int myId = 2;
var matchingRecord = context.MyLargeTable.Where(v=>v.Id == myId).ToList(); //Super slow (5+ minutes, sometimes Out of Memory exception)


int myId = 2;
Expression<Func<bool>> myLambda = v => v.Id == myId; //Shouldn't this work now?
var matchingRecord = context.MyLargeTable.Where(myLambda).ToList(); //Still super slow (5+ minutes, sometimes Out of Memory exception)


var elementName = Expression.Parameter(typeof(LargeTable), "v");
var propertyName = Expression.Parameter(elementName, "Id");
var constantValue = Expression.Constant(myId);
var comparisonMethod = Expression.Call(
propertyName,
typeof(int).GetMethod("Equals", new[] { typeof(int) }),
constantValue
)
var finalTree = Expression.Lambda<Func<LargeTable, bool>>(comparisonMethod, elementName);
var matchingRecord = context.MyLargeTable.Where(finalTree).ToList(); //Super fast

Я читал такие вещи, которые объясняют разницу между Func‹> и Expression> и то, как Expression> на самом деле передается в базу данных для запроса, и поэтому он быстрее.

http://www.fascinatedwithsoftware.com/blog/post/2011/12/02/Falling-in-Love-with-LINQ-Part-7-Expressions-and-Funcs.aspx - В целом все хорошо, но если вы спешите, просто прочитайте раздел «Непреднамеренные последствия», чтобы узнать о главном.

http://fascinatedwithsoftware.com/blog/post/2012/01/10/More-on-Expression-vs-Func-with-Entity-Framework.aspx

Почему вы должны использовать Expression‹Func‹T››, а не Func‹T ›? — ни один набор ссылок не будет полным без соответствующего вопроса SO

Мой вопрос таков: действительно ли люди сидят и строят деревья выражений, используя классы Expression.*? Любой запрос, выходящий за рамки простых сравнений, становится очень сложным и почти нечитаемым. Что мне не хватает в передаче Expression> в базу данных? Кого я могу ударить по лицу за это решение дерева выражений, построенное вручную? Оракул? ЭФ? Что мне не хватает?


person IrishBoiler    schedule 10.08.2012    source источник
comment
Я предполагаю, что первый запрос на самом деле является context.MyLargeTable.Where(v=›v.Id == myId).ToList() (где отсутствует). Если это так, он должен быть эквивалентен последнему. Из того, что вы написали, похоже, что .Where неправильно переведен в SQL. Можете ли вы проверить, какие SQL-запросы отправляются в базу данных? Вам не нужно создавать деревья выражений вручную — по крайней мере, для обычных задач. Есть некоторые крайние случаи, когда это полезно (например, stackoverflow.com/questions/10402029/), но в целом вам не нужно этого делать.   -  person Pawel    schedule 22.08.2012
comment
@Pawel Вы правы, мне не хватает .Where в вопросе. Запросы SQL верны, когда я передаю дерево выражений, но когда я использую обычную лямбду, кажется, что часть предложения Where при переходе к Oracle отбрасывается.   -  person IrishBoiler    schedule 22.08.2012
comment
Не могли бы вы подготовить небольшой репро? Будет сложно понять, в чем проблема, не пройдясь по коду.   -  person Pawel    schedule 22.08.2012