Перехват не работает должным образом с Entity Framework 6

Я пытаюсь следовать приведенному здесь примеру перехвата, чтобы заставить его работать с EF 6, но столкнулся с проблемой с функцией RewriteFullTextQuery как показано на рисунке 1. Перехват, кажется, работает, но на самом деле он не выполняет логику в for петля RewriteFullTextQuery метод, потому что cmd.Parameters.Count всегда ноль. Кроме того cmd.CommandText свойство, похоже, отображает правильный SQL-запрос, который я считаю еще одним доказательством того, что перехват работает правильно.

Рисунок 1: фрагмент кода RewriteFullTextQuery

 public static void RewriteFullTextQuery(DbCommand cmd)
    {
        string text = cmd.CommandText;
        for (int i = 0; i < cmd.Parameters.Count; i++)
        {
            DbParameter parameter = cmd.Parameters[i];
            if (parameter.DbType.In(DbType.String, DbType.AnsiString, DbType.StringFixedLength, DbType.AnsiStringFixedLength))
            {

Функция RewriteFullTextQuery вызывается ReaderExecuting функция, показанная на рисунке 2, которая дает ему аргумент команды, который вызывает все проблемы.

Рисунок 2: Функция ReaderExecuting

public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        RewriteFullTextQuery(command);
    }

Хотя мой код не совсем такой, как в примере, перехват, кажется, работает, поэтому я задаюсь вопросом, какие условия заполняют команду для получения Parameters.Count больше нуля?

2 ответа

Решение

Оказывается, это из-за способа, которым Entity Framework генерирует SQL. Если вы передаете строковый литерал в качестве значения поиска в оператор LINQ, он не генерирует SQL, который использует параметр. Но если вы передадите поисковое значение как переменную, он сгенерирует SQL, который использует параметр. Решение (для динамических запросов) и более подробную информацию можно найти в этом блоге.

Это работает, только если вы передаете параметр в запрос в качестве переменной. Если вы используете буквальный EF не будет использовать параметры.
Я имею в виду, это не будет генерировать никаких параметров

context.Notes.Where(_ => _.NoteText == "CompareValue").Count();

Это будет

string compareValue = "CompareValue";
context.Notes.Where(_ => _.NoteText == compareValue).Count();
Другие вопросы по тегам