[英]Lambda expression weirdness in a LINQ to SQL 'where' condition
我正在开发一个ASP.NET MVC应用程序,它使用带有LINQ to SQL的存储库模式作为我的数据源。 在我的存储库中,我公开了以下方法:
public IEnumerable<T> Find(Expression<Func<T, bool>> where)
{
return _context.GetTable<T>().Where(where);
}
我可以这样说:
repository<User>().Find(u => true);
但是,如果我尝试做(当搜索为空时)
repository<User>().Find(u => !string.IsNullOrEmpty(search) ? u.UserName.Contains(search) : true);
我收到错误:
值不能为空。 参数名称:文本
我认为lambda表达式将执行相同的操作,因为search的值为null,但显然不是这种情况。
我该如何解决这个问题?
因为这是一个表达式,所以不会自动应用正常的条件运算符逻辑(不评估false表达式)。 由于表达式实际上被转换为SQL查询表达式,LINQ to SQL正在评估条件的参数,在这种情况下它是null
。 虽然LIKE null
是有效的SQL语法,但显然LINQ to SQL不赞赏传递null。 您将不得不构造两个不同的查询,一个用于空术语,一个用于非空术语。
要么是这样,要么将string.Empty
传递给Contains
。 这里唯一的影响是无法在列上使用索引,因为服务器将对每一行进行重复的条件评估,从而强制进行表扫描。 我建议在没有条件的情况下使用两个查询。
包含一个字符串。 你应该传递string.Emtpy
。
u.UserName.Contains(search)
如果你试试这个,它会编译,但你会得到一个运行时错误:
string str = "Leniel";
if (str.Contains(null))
{
var num = 1;
}
错误:
Value cannot be null.
Parameter name: value
要添加其他答案,如果你必须遵循这个理想,你可以简单地这样做:
repository<User>.Find(u => string.IsNullOrEmpty(search) ||
u.UserName.Contains(search));
在盲目实施之前,如果你这样做,请阅读亚当的答案以了解后果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.