题
我有这个:
var sortName = Request.Params["sortName"];
var query = Request.Params["query"];
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
"uen.GetPropValue<string>(sortName)"
将使用用户在页面中键入的sortName动态填充。
例如,如果用户查找名为<!>“Joe <!>”的人,则该代码段将为:
(uen => uen.namePerson.Contains(Joe))
但是,我遇到了LINQ区分大小写的搜索问题。如果我输入<!>“Joe <!>”,我会做点什么。另一方面,如果我输入<!>“; joe <!>”,它什么都没带。
如何制作<!>“;包含(sortName)<!>”;使用Case-Insensitive?我已经尝试了一些String.Comparer的东西,但它报告了构建解决方案的错误。
谢谢!
解决方案
我相信以下内容将生成正确的SQL:
uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
其他提示
如果这确实是LINQ-to-SQL,请尝试使用 SqlMethods.Like 方法而不是String.Contains。
但是,我认为问题在于这不是LINQ-to-SQL,因为您使用的是委托而不是表达式树。所以这是客户端,然后在本地执行(<!> quot; LINQ to Objects <!> quot;)。因此,String.Contains正在做本地的工作。
通过这种方式,詹姆斯的回答是正确的,因为他在值和查询上都调用了ToLower()。 (虽然,要注意文化问题 - 也许要指明你想要的文化。)
您还可以使用String.IndexOf方法(String,Int32,StringComparison)( http://msdn.microsoft.com/en-us/library/ms224424.aspx )。此方法允许您指定匹配是否应区分大小写,以及是否应使用不变文化。
所以在你的例子中:
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));
我不是在评论这是否比James Curran提供的更好的解决方案。它可能是也可能不是,表现明智。
这是整个代码:
var sortOrder = Request.Params["sortorder"];
var sortName = Request.Params["sortname"];
var query = Request.Params["query"];
IEnumerable<UsuarioEndereco> pagedEndereco;
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
pagedEndereco = sortOrder.Equals("asc", StringComparison.CurrentCultureIgnoreCase) ?
_agendaServico.SelecionaUsuarioEnderecos(u.codUsuario).Where(whereClause).OrderByDescending(uen => uen.GetPropValue<IComparable>(sortName)) :
_agendaServico.SelecionaUsuarioEnderecos(u.codUsuario).Where(whereClause).OrderBy(uen => uen.GetPropValue<IComparable>(sortName));
扩展方法GetPropValue是:
public static T GetPropValue<T>(this object component, string propertyName)
{
return (T)TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}