tags:

views:

218

answers:

3

I am reading contradictory explanations on Linq to Sql string comparisons.

When I do the following:

  from p in db.People 
  where p.UserName=username
  select p

username="jOHn"

I get the correct case insensitive result. Is Linq doing this by default or is this happening in SQL database?

+1  A: 

It depends on the database. SQL Server 2008 treats strings as case-insensitive, including when used in an index expression. Linq does not do that.

Read on MSDN, or this article.

cdonner
Case sensitivity / insensitivity is dependent on what collation you use in your database and/or the columns involved (default is set when sql server is installed, but it can be overridden in several places, down to the column level).
KristoferA - Huagati.com
+2  A: 

I think you get conflicting results based on what your db variable points to and where the compare is actually executed. If it can, linq will build the query and send it to the SQL server. It seems like you could force case insensitive by calling

where p.UserName.ToLower()=username.ToLower()
Jeff Martin
Sorry, but this is bad advice. p.UserName.ToLower()=username.ToLower() will translate to a SQL query that will force a full table scan. That doesn't matter if the "people" table is small, but if it is a large table then it will not be able to use any index that may cover the 'username' column.
KristoferA - Huagati.com
+3  A: 

Your sample query will translate to something roughly like this:

select [t0].col1, [t0].col2, ..., [t0].coln from [schema].[People] where [t0].UserName = @p0

...the value in the username variable will be passed in the @p0 sql variable. As such, case sensitivity, accent sensitivity etc is controlled by the collation you have set up your SQL Server instance/db/table/column to use. If not specified anywhere else, the DBs or DB instance's default collation is used, but collation can be specified all the way down to the column level.

Most people run SQL Server with case insensitive (CI) collations but as I have said above, it can be overridden in the DB so you just need to check what collation you have there.

This is in contrast to if you do the same thing as a L2O (linq to objects) query, in that case case-sensitivity is the default and you would have to make it case insensitive by using the string.equals override that allow you to specify culture and/or case insensitivity...

KristoferA - Huagati.com
wouldn't using a string.equals override have the same problem you commented on with my result? Force all the records to come to the linq side to do the comparison?
Jeff Martin
@Jeff, The string.equals reference was just a comparison between how L2S and L2O behaves, sorry if I wasn't clear on that point. But yes, if you would combine the two and do the evaluation on the client side as a L2O query then it would not only get all records but also send them over the wire. In other words, using the right collation is key here.The example from your reply would still be evaluated in the database, but with the extra overhead of a table scan due to the function call wrapper on the left hand side where clause predicate.
KristoferA - Huagati.com
Thanks for the response (I gave +1 when i made the earlier comment)
Jeff Martin