«Для метода String.Contains поддерживаются только аргументы, которые можно оценить на клиенте» - PullRequest
6 голосов
/ 09 ноября 2009
public static void MyFunction(MyErrorClass err)
{
    var query = from filter in DataContext.ErrorFilters select filter;
    query = query.Where(f => err.ErrorMessage.Contains(f.ErrorMessage));
    List<ErrorFilter> filters = query.ToList();
    //...more code
}

Итак, у меня возникли некоторые проблемы с приведенным выше кодом, и я получаю сообщение об ошибке из строки темы в строке с query.ToList(). Вот что я пытаюсь сделать:

Во-первых, у меня есть собственный класс ошибок, MyErrorClass. Всякий раз, когда происходит ошибка на моем сайте, я создаю объект MyErrorClass из исключения, сохраняю все данные из исключения в этом объекте и сохраняю информацию в базе данных.

Одним из свойств исключения, которое я отслеживаю, является сообщение об ошибке (ErrorMessage). У меня есть таблица ErrorFilters, настроенная в базе данных, где пользователь может фильтровать ошибки на основе ErrorMessage. Допустим, вы получаете кучу ошибок, которые говорят «System.Data.SqlClient.SqlException: Timeout expired. Период ожидания истек до завершения операции или сервер не отвечает», и вы хотите их игнорировать. Вы просто добавляете фильтр в базу данных с сообщением ErrorMessage как «истекло время ожидания» и устанавливаете его игнорируемым.

Теперь мой класс выше настроен так, чтобы принимать ошибку и решать, следует ли отфильтровать ошибку. Я пытаюсь получить список всех фильтров, которые имеют ErrorMessage, совпадающий с ошибкой.

Я уверен, что это легко исправить, я просто не знаю, как это исправить.

Ответы [ 2 ]

8 голосов
/ 18 июля 2014

Хмм ... Кажется, перевод Linq2SQL IndexOf умнее, чем для Contains. Это должно работать:

public static void MyFunction(MyErrorClass err)
{
    var query = DataContext.ErrorFilters;
    query = query.Where(f => err.ErrorMessage.IndexOf(f.ErrorMessage)>=0);
    List<ErrorFilter> filters = query.ToList();
    //...more code
}

В LinqPad видно, что используется CHARINDEX, потому что мы просили больше, чем просто «содержит», а не «где это», но мы рады работать с серверными выражениями.

0 голосов
/ 10 ноября 2009

Кажется, вы должны использовать f.ErrorMessage.Contains(err.ErrorMessage) - linq в sql должен преобразовать это в WHERE ErrorFilter.ErrorMessage LIKE %err.ErrorMessage%. Проблема, связанная с тем, что у вас есть, заключается в том, что сгенерированному SQL потребуется динамическая строка для сопоставления в предложении where, и, следовательно, она может быть отфильтрована только на клиенте.

Кстати, строка var query = from filter in DataContext.ErrorFilters select filter; не требуется, и вы можете просто сделать:

var filters = DataContext.ErrorFilters.Where(f => f.ErrorMessage.Contains(err.ErrorMessage)).ToList();

EDIT:

Хорошо, теперь я вижу, что вы пытаетесь сделать, но я не уверен, возможно ли это в linq2sql. Вы можете создать хранимую процедуру и добавить ее к текстовому тексту данных и выполнить сопоставление выходных данных с последовательностью объектов ErrorFilter:

create procedure GetMatchingFilters @message varchar(500)
as
begin
    select  *
    from ErrorFilter
    where @message LIKE '%'+ErrorMessage+'%'
end

Тогда в вашем тексте данных вы можете сделать:

DataContext
    .GetMatchingFilters(err.ErrorMessage)
    .Select(result => new ErrorFilter {...})
    .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...