views:

2897

answers:

4

Hi!

I have this:

var sortName = Request.Params["sortName"];
var query = Request.Params["query"];

Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));

The "uen.GetPropValue<string>(sortName)" will be filled dynamically with the sortName the user typed in the page.

For example, if an user looks for a person named "Joe", the snippet will be:

(uen => uen.namePerson.Contains(Joe))

But, I'm having problems with LINQ Case-sensitive searches. If I type "Joe", I will something. On the other hand, If I type "joe", it bring nothing.

How can I make this "Contains(sortName)" works with Case-Insensitive?? I've tried some things with String.Comparer but it reports errors on build solution.

Thanks!!

+4  A: 

I believe the following will generate proper SQL:

 uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
James Curran
James, it didn't work 'cause it will only work if records in database are recorded in lowerletters ("joe", for example). For example: In my database, I have "Joe" recorded. If I type "Joe" in my page, it will show result. If I type "joe" it will show nothing 'cause the case sensitive.
AndreMiranda
Which is why I put ToLower of both sides of the Contains()
James Curran
oh man! Sorry! I did NOT see the ToLower before!! It worked just fine! Thanks a lot!!
AndreMiranda
Caution with this code because in languages with accents you may also want to remove them (create an extension method for that and call it before .ToLower(), for example).
Marc Climent
+2  A: 

If this is really LINQ-to-SQL, try using the SqlMethods.Like method instead of String.Contains.

However, I think the problem is that this is NOT LINQ-to-SQL, because you are using delegates instead of Expression trees. So this is being brought client side, then executed locally ("LINQ to Objects"). Hence, String.Contains is doing what it does locally.

In that way, James's answer is correct, since he's calling ToLower() on both the value and the query. (Although, beware of culture issues -- perhaps specify which culture you want.)

MichaelGG
A: 

This is the entire code:

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

The Extension Method GetPropValue is:

public static T GetPropValue<T>(this object component, string propertyName)
{
    return (T)TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}
AndreMiranda
You should move this into to your question.
RichardOD
+1  A: 

You could also use the String.IndexOf Method (String, Int32, StringComparison) (http://msdn.microsoft.com/en-us/library/ms224424.aspx). This method allows you to specify if the matching should be done case-sensitively or not, and if it should use a Invariant culture or not.

So in your example:

Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));

I'm not commenting on if this is a better solution than the one provided by James Curran. It could or could not be, performance wise.

MichaelvR