Странные проблемы с ядром ef при применении фильтра - PullRequest
0 голосов
/ 22 мая 2019

У меня очень странная проблема. Я заметил, что эта проблема возникает только при применении фильтра. (проверьте комментарии в коде для получения дополнительной информации)

Трассировка стека: enter image description here Код:

if (!string.IsNullOrEmpty(searchTerm)) // If that pass only then i got exception!
{
    query = query.Where(FilterBySearchTerm2(searchTerm));
}

var count = await query.CountAsync(); // here is the exception
var totalPages = (int)Math.Ceiling(count / (double)Pagination.DefaultPageSize);

- метод фильтрации

private Expression<Func<User, bool>> FilterBySearchTerm(string searchTerm)
{
    return u => u.FirstName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.MiddleName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.LastName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.FullName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase) // FullName is NotMapped property in the User class!
        || u.Company.Name.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.Email.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.Address.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.IncorporationNumber.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.DirectorFullName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.DirectorEmail.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.DirectorPhone.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Phone.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Email.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        || u.Company.CompanyPrograms.Any(cp => cp.Program.Name.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase));
        }

- Свойство FullName в классе пользователя

 [NotMapped]
 public string FullName => string.IsNullOrEmpty(this.MiddleName) ?
      $"{this.LastName} {this.FirstName}" :
      $"{this.LastName} {this.FirstName} {this.MiddleName}";

Кажется, это очень глубоко в ядре платформы сущностей, но я не знаю, является ли это ошибкой или ожидается, что она будет работать именно так.

UPDATE Я проверил с более простым выражением, и я нашел следующее:

Не работает:

 return u => u.FirstName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)

Работа:

 return u => u.FirstName.Contains(searchTerm)

Работа:

 return u => u.FullName.Contains(searchTerm)

Не работает:

return u => u.FirstName.Contains(searchTerm) 
     || u => u.MiddleName.Contains(searchTerm)
     || u => u.LastName.Contains(searchTerm) 
     || u => u.FullName.Contains(searchTerm) 

1 Ответ

1 голос
/ 22 мая 2019

Я попытаюсь объяснить это настолько просто, насколько смогу.

Сначала убедитесь, что значения, к которым вы применяете фильтр, не равны null.

Потому что, если вы попытаетесь вызвать функцию со значением null, такое исключение будет выдано.

например:

var keyword = "some key word";
string firstName = "John";
string lastName = null;

if(firstName.contains(keyword, StringComparison.InvariantCultureIgnoreCase)){
     //No exception would be thrown,
     //because it is like "john".contains("some key word", StringComparison.InvariantCultureIgnoreCase)
}


if(lastName.contains(keyword, StringComparison.InvariantCultureIgnoreCase)){
     //An exception would be thrown,
     //because it is like null.contains("some key word", StringComparison.InvariantCultureIgnoreCase)
}

Причина, по которой FullName работает, заключается в том, что это комбинация (FirstName, MiddleName и LastName), и я уверен, что это space-separated, поэтому FullName никогда не будет null, если все объединенные пропиаты равны нулю, это было бы как .

Обновление:

string firstName = null;
string lastName = null;
var fullName = $"{firstName} {lastName}"; //or fullName = firstName + " " + lastName;

if(fullName.contains(keyword, StringComparison.InvariantCultureIgnoreCase)){
     //No exception would be thrown,
     //because it is like "  ".contains("some key word", StringComparison.InvariantCultureIgnoreCase)
}


Обновление: Примечание: IMO, вам не нужно применять фильтр к (FirstName, MiddleName и LastName), поскольку их значения находятся в пределах FullName, так что вы можете удалить условие проверки для них и сохранить FullName с помощью остаток фильтра.

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