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

时间:2019-05-22 15:24:54

标签: c# asp.net-core entity-framework-core

我有一个很奇怪的问题。我注意到,仅当应用过滤器时才引起此问题。 (请查看代码中的评论以获取更多信息)

堆栈跟踪: enter image description here 代码:

SELECT a.id, b.id FROM a a
                        JOIN b b ON b_id=id
                        JOIN c c ON c_id=id
                        JOIN d d ON d_id=id
WHERE nvl(c.col1, '')='col1'
  AND c.col_date <= TO_DATE('2019-05-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
  AND c.col_date >= TO_DATE('2019-01-14 00:00:00', 'yyyy-mm-dd hh24:mi:ss')

-过滤方法

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

-用户类中的FullName属性

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

这似乎在实体框架核心中非常深入,但是我不知道这是一个错误还是可以像这样正常工作。

更新 我已经测试了较简单的表达式,发现以下内容:

不工作:

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

工作:

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

工作:

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

不工作:

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

1 个答案:

答案 0 :(得分:1)

我将尽我所能简单地解释它。

首先,请确保您要应用过滤器的值不是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永远不会{ {1}},如果所有组合的属性均为null,则类似于null

更新:


更新: 注意: IMO,您不需要将过滤器应用于(名字,中间名和姓氏),因为它们的值在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) } 之内,因此您可以删除它们的检查条件并保留{ {1}}和其他过滤器。