Linq to SQL case sensitivity causing problems

Posted by Roger Lipscombe on Stack Overflow See other posts from Stack Overflow or by Roger Lipscombe
Published on 2009-10-30T11:04:55Z Indexed on 2010/05/31 11:02 UTC
Read the original article Hit count: 451

I've seen this question, but that's asking for case-insensitive comparisons when the database is case-sensitive. I'm having a problem with the exact opposite.

I'm using SQL Server 2005, my database collation is set to Latin1_General_CI_AS.

I've got a table, "User", like this:

CREATE TABLE [dbo].[User] (
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](max) NOT NULL,
	CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED (
		[Id] ASC
	)
)

And I'm using the following code to populate it:

string[] names = new[] { "Bob", "bob", "BoB" };
using (MyDataContext dataContext = new AppCompatDataContext())
{
    foreach (var name in names)
    {
        string s = name;
        if (dataContext.Users.SingleOrDefault(u => u.Name == s) == null)
            dataContext.Users.InsertOnSubmit(new User { Name = name });
    }

    dataContext.SubmitChanges();
}

When I run this the first time, I end up with "Bob", "bob" and "BoB" in the table.

When I run it again, I get an InvalidOperationException: "Sequence contains more than one element", because the query against the database returns all 3 rows, and...

SELECT * FROM [User] WHERE Name = 'bob'

... is case-insensitive.

That is: when I'm inserting rows, Linq to SQL appears to use C# case-sensitive comparisons. When I query later, Linq to SQL uses SQL Server case-insensitive comparisons.

I'd like the initial insert to use case-insensitive comparisons, but when I change the code as follows...

if (dataContext.Users.SingleOrDefault(u => 
        u.Name.Equals(s, StringComparison.InvariantCultureIgnoreCase)
   ) == null)

... I get a NotSupportedException: "Method 'Boolean Equals(System.String, System.StringComparison)' has no supported translation to SQL."

Question: how do I get the initial insert to be case-insensitive or, more precisely, match the collation of the column in the database?

Update: This doesn't appear to be my problem. My problem appears to be that SingleOrDefault doesn't actually look at the pending inserts at all.

© Stack Overflow or respective owner

Related posts about linq-to-sql

Related posts about case-sensitive