LINQ to Entities无法识别方法IsNullOrWhiteSpace

Joh*_*van 5 c# linq-to-entities linq-to-sql entity-framework-6 asp.net-mvc-5

我有以下代码:

var countries = from c in db.Countries
    where (string.IsNullOrWhiteSpace(searchAlpha2) || (c.Alpha2 ?? string.Empty).ToUpper().Contains(searchAlpha2.ToUpper()))
    && (string.IsNullOrWhiteSpace(searchAlpha2) || (c.Alpha3 ?? string.Empty).ToUpper().Contains(searchAlpha3.ToUpper()))
    && (string.IsNullOrWhiteSpace(searchName) || (c.Name ?? string.Empty).ToUpper().Contains(searchName.ToUpper()))
    select c;
Run Code Online (Sandbox Code Playgroud)

此代码在SQL数据库上使用Entity Framework v6 Code First.

除了性能之外,如果我不包括IsNullOrWhitespace我在过滤条件为空时没有得到结果(我已经测试了空值和空值); 但是当值存在时,这可以按预期工作.

我收到错误:

LINQ to Entities does not recognize the method 'Boolean IsNullOrWhiteSpace(System.String)' method, and this method cannot be translated into a store expression.
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用searchXXX字符串来过滤列.我已经尝试过使用RegEx.IsMatch,SqlMethods.Like和下面的代码,但是所有这些都给我错误,说明这些函数是不允许的(错误来自EntityFramework.SqlServer或来自Linq to Entities).我已经看到很多帖子在这里成功完成了 - 所以我想知道我是否遗漏了一些基本的东西?

Mat*_*ius 10

如果要以当前形式使用语句,可能需要替换

string.IsNullOrWhiteSpace(searchAlpha2)
Run Code Online (Sandbox Code Playgroud)

!(searchAlpha2 == null || searchAlpha2.Trim() == string.Empty)
Run Code Online (Sandbox Code Playgroud)

以及所有其他值,因为它被转换为工作SQL.


Stu*_*tLC 5

我建议采用不同的方法 - 使用能够动态构建查询,从而避免将可选的查询参数完全传递给表达式 - 这将导致在解析为sql并在数据库上执行时改进的查询计划.

此外,如果您的数据库(?SqlServer)未设置为区分大小写的排序规则(即xx_CI_xx),则可以避免大小写转换,因为它是多余的:

var myQueryable = db.Countries.AsQueryable();

if (!string.IsNullOrWhiteSpace(searchAlpha2))
{
    myQueryable = myQueryable.Where(c => c.Alpha2.Contains(searchAlpha2));
}
...

var countries = myQueryable.ToList();
Run Code Online (Sandbox Code Playgroud)

您可以使用PredicateBuilder获得此功能和更多功能

更新

JB:根据StuartLC的回答,这里修改了使用PredicateBuilder的代码:

var predicate = PredicateBuilder.True<Country>();
if (!string.IsNullOrWhiteSpace(searchAlpha2))
    predicate = predicate.And(c => c.Alpha2 != null ? c.Alpha2.Contains(searchAlpha2) : false);
if (!string.IsNullOrWhiteSpace(searchAlpha3))
    predicate = predicate.And(c => c.Alpha3 != null ? c.Alpha3.Contains(searchAlpha3) : false);
if (!string.IsNullOrWhiteSpace(searchName))
    predicate = predicate.And(c => c.Name != null ? c.Name.Contains(searchName) : false);

IQueryable<Country> countries = db.Countries.AsExpandable().Where(predicate);
Run Code Online (Sandbox Code Playgroud)

  • 很棒的提示; 我之前没遇到过PredicateBuilder; 谢谢. (2认同)