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.
我建议采用不同的方法 - 使用能够动态构建查询,从而避免将可选的查询参数完全传递给表达式 - 这将导致在解析为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)
| 归档时间: |
|
| 查看次数: |
6382 次 |
| 最近记录: |