C#LINQ问题区分大小写

时间:2009-03-06 17:50:30

标签: linq-to-sql c#-3.0

我有这个:

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”,它什么也没带。

如何使“Contains(sortName)”与Case-Insensitive一起使用?我已经尝试了一些String.Comparer的东西,但它报告了构建解决方案的错误。

谢谢!

4 个答案:

答案 0 :(得分:6)

我相信以下内容将生成正确的SQL:

 uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))

答案 1 :(得分:2)

如果这确实是LINQ-to-SQL,请尝试使用SqlMethods.Like方法而不是String.Contains。

但是,我认为问题在于这不是LINQ-to-SQL,因为您使用的是委托而不是表达式树。所以这是客户端,然后在本地执行(“LINQ to Objects”)。因此,String.Contains正在做本地的工作。

通过这种方式,詹姆斯的回答是正确的,因为他在值和查询上都调用了ToLower()。 (虽然,要注意文化问题 - 也许要指明你想要的文化。)

答案 2 :(得分:1)

您还可以使用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提供的更好的解决方案。它可能是也可能不是,表现明智。

答案 3 :(得分:0)

这是整个代码:

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