Создание параметризованного основного выражения EntityFramework - PullRequest
0 голосов
/ 07 января 2019

Привет, я пытаюсь построить выражение, чтобы получить универсальную сущность по ее первичному ключу и получить параметризованный SQL-запрос.

В настоящее время я могу получить правильный запрос WHERE, но он не параметризован.

public async Task<TDbo> Get(TKey key, Expression<Func<TEntity, TKey>> keySelector)
{
    var propertyRef = keySelector.Body;
    var parameter = keySelector.Parameters[0];
    var constantRef = Expression.Constant(key);
    var equals = Expression.Equal(propertyRef, constantRef);
    var comparer = Expression.Lambda<Func<TEntity, bool>>(equals, parameter);

    return await _context.Set<TDbo>().SingleOrDefaultAsync(comparer);
}

Это приводит к следующему запросу: SELECT e.\"Id\", e.\"Name\" \r\n FROM \"People\" AS e\r\nWHERE e.\"Id\" = 1\r\nLIMIT 2, вместо разыскиваемого SELECT e.\"Id\", e.\"Name\" \r\n FROM \"People\" AS e\r\nWHERE e.\"Id\" = @__s_0\r\nLIMIT 2

1 Ответ

0 голосов
/ 07 января 2019

Это из-за Expression.Constant(key). Постоянные выражения значения не параметризуются транслятором запроса. Вам нужно выражение, ссылающееся на свойство или поле другого выражения (которое может быть константой). Это в основном то, что компилятор C # испускает для замыканий.

Одним из способов является использование компилятора C # для создания лямбда-выражения с замыканием и получения тела:

Expression<Func<TKey>> keyValue = () => key;
var variableRef = key.Body;

(variableRef является заменой вашего constantRef)

Другой способ - использовать анонимный, кортежный или определенный тип класса для создания явного экземпляра замыкания и связывания соответствующего свойства или поля. Например, с анонимным типом:

var variableRef = Expression.Property(Expression.Constant(new { key }), "key");

или System.Tuple:

var variableRef = Expression.Property(Expression.Constant(Tuple.Create(key)), "Item1");

Реальный метод на самом деле не имеет значения (лично я предпочитаю первый вариант с лямбдой) - все они будут вызывать создание параметра с помощью транслятора запросов EF Core.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...