Linq IQueryable короткое замыкание пустого параметра поиска - PullRequest
1 голос
/ 25 ноября 2010

У меня есть общий репозиторий по следующему методу

IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression);

Я сейчас пытаюсь предоставить функцию поиска через интерфейс, где один или несколько параметров могли быть введены или оставлены пустыми.У меня проблемы с замыканием выражения для пустых параметров.

Проблема может быть продемонстрирована путем вызова следующего примера в хранилище:

public IEnumerable<Foo> Search(string param)
{
    var filteredFoos = _fooRepository.GetAllByFilter(
          f => string.IsNullOrEmpty(param) || f.Something == param );

    return filteredFoos.ToList(); // throws exception
}

Перечисление запроса с помощью ToList()выдает System.NullReferenceException, если param равно null.

Я не понимаю этого и не знаю, как это исправить, поэтому любые указатели приветствуются.Благодарю.

ОБНОВЛЕНИЕ: в ответ на комментарии ниже я добавил нулевую проверку.Мой реальный код теперь выглядит так

var test1 = _repository.GetAllByFilter(
     r => r != null && 
         (string.IsNullOrEmpty(param) 
              || (r.Field != null && r.Field.IndexOf(param.Trim()) != -1)));

var test2 = test1.ToList(); // exception here

Я до сих пор не вижу, где может быть проблема.

РЕДАКТИРОВАТЬ: в ответ на комментарий, общий репозиторийGetAllByFilter код:

public IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression)
{
    return _dataContext.GetTable<T>().Where(expression);
}

обратите внимание, что если я выполню простой GetAll запрос

public IQueryable<T> GetAll()
 {
     return _dataContext.GetTable<T>();
 }

для той же таблицы, null записей не будет возвращено (как и ожидалось).

Ответы [ 2 ]

2 голосов
/ 20 мая 2011

будь проще:

public IEnumerable<Foo> Search(string param)
{
    if (string.IsNullOrEmpty(param))
    {
        return this.fooRepository.GetAll().ToArray();
    }

    return this.fooRepository.GetAllByFilter(o => o.Field.Contains(param.Trim())).ToArray();
}
0 голосов
/ 20 мая 2011

торт.

    public IEnumerable<Foo> Search(string param)
    {
        Expression<Func<Foo, bool>> shortCircuit = a => true;
        Expression<Func<Foo, bool>> normal = a => a.Something == param;

        var filteredFoos = _fooRepository.GetAllByFilter(
            string.IsNullOrEmpty(param) ? shortCircuit : normal);

        return filteredFoos.ToList(); // no more exception.
    }

Вы просто должны помнить, вы не можете ничего добавить в эти методы IQueryable и ожидать, что они поймут. Вы, вероятно, можете сделать выражение shortCircuit статическим.

...