Когда EF или LINQ to SQL запускает запрос, он:
- Создает дерево выражений из кода,
- Преобразует дерево выражений в запрос SQL,
- Выполняет запрос, получает необработанные результаты из базы данных и преобразует их в результат, который будет использоваться приложением.
Посмотрев на трассировку стека, я не могу понять, где происходит вторая часть.
В общем, можно ли использовать существующую часть EF или (желательно) LINQ to SQL для преобразования объекта Expression
в частичный SQL-запрос (с использованием синтаксиса Transact-SQL), или я должен изобретать колесо
Обновление: комментарий просит предоставить пример того, что я пытаюсь сделать.
На самом деле, ответ Райана Райт ниже отлично иллюстрирует то, что я хочу достичь в результате, за исключением того, что мой вопрос конкретно о том, как я могу это сделать используя существующие механизмы .NET Framework, которые фактически используются EF и LINQ to SQL, вместо того, чтобы изобретать колесо и записывать тысячи строк не так проверенного кода, я сам делал аналогичную вещь.
Вот пример. Опять же, обратите внимание, что не существует кода, генерируемого ORM.
private class Product
{
[DatabaseMapping("ProductId")]
public int Id { get; set; }
[DatabaseMapping("Price")]
public int PriceInCents { get; set; }
}
private string Convert(Expression expression)
{
// Some magic calls to .NET Framework code happen here.
// [...]
}
private void TestConvert()
{
Expression<Func<Product, int, int, bool>> inPriceRange =
(Product product, int from, int to) =>
product.PriceInCents >= from && product.PriceInCents <= to;
string actualQueryPart = this.Convert(inPriceRange);
Assert.AreEqual("[Price] between @from and @to", actualQueryPart);
}
Откуда появляется имя Price
в ожидаемом запросе?
Имя может быть получено путем отражения путем запроса пользовательского атрибута DatabaseMapping
свойства Price
класса Product
.
Откуда возникают имена @from
и @to
в ожидаемом запросе?
Эти имена являются фактическими именами параметров выражения.
Откуда between … and
из ожидаемого запроса?
Это возможный результат двоичного выражения. Возможно, вместо EF или LINQ to SQL вместо оператора between … and
следует придерживаться [Price] >= @from and [Price] <= @to
. Это тоже нормально, это не имеет большого значения, поскольку результат логически одинаковый (я не упоминаю о производительности).
Почему в ожидаемом запросе нет where
?
Потому что ничто не указывает в Expression
, что должно быть ключевое слово where
. Возможно, фактическое выражение является лишь одним из выражений, которые позже будут объединены с бинарными операторами, чтобы построить более крупный запрос для добавления с помощью where
.