简体   繁体   English

应用过滤器时ef核心的怪异问题

[英]Weird problems with ef core when filter is applied

I have a very weird problem. 我有一个很奇怪的问题。 I have noticed that this problem is caused only when a filter is applied. 我注意到,仅当应用过滤器时才引起此问题。 (check comments in the code for more info) (检查代码中的注释以获取更多信息)

Stack trace: 堆栈跟踪: 在此处输入图片说明 Code: 码:

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);

-- Filter method -过滤方式

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 property in User class -User类中的FullName属性

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

That seems to be very deep in entity framework core, but I don't know if that's a bug or its expected to work like that. 这似乎在实体框架核心中非常深入,但是我不知道那是一个错误还是可以像这样正常工作。

UPDATE I have tested with simpler expression and I found the following: 我用更简单的表达式测试了UPDATE ,发现以下内容:

Don't work: 不工作:

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

Work: 工作:

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

Work: 工作:

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

Don't work: 不工作:

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

I am going to try to explain it as simple as i can.. 我将尝试尽可能简单地解释它。

First, please make sure that the values you are applying the filter to are not null . 首先,请确保您要应用过滤器的值不为null

Because if you try to call a function over a null value such an exception would be thrown. 因为如果您尝试通过null值调用函数,则会引发此类异常。

Eg: 例如:

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)
}

The reason why FullName works is that because it is a combination of (FirstName, MiddleName, and LastName) and i am sure it is space-separated so the FullName would never be null , if all the combined propitiates are null it would be like FullName起作用的原因是,因为它是(FirstName,MiddleName和LastName)的组合,并且我确信它是用space-separated所以FullName永远不会为null ,如果所有组合的proppropates都是null,它将是 .

Update: 更新:

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)
}


Update: Note: IMO you do not need to apply the filter to (FirstName, MiddleName, and LastName) because their values are within the FullName so you can remove the check condition for those and keep FullName with the rest of the filter. 更新: 注意: IMO,您不需要将过滤器应用于(名字,中间名和姓氏),因为它们的值在FullName内,因此您可以删除这些检查条件,并将FullName与过滤器的其余部分一起保留。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM