Travyguy9
Travyguy9

Reputation: 4344

String.Equals() not working as intended

I am using LINQ to search through one of my Entity Framework tables and find a "group" based on the name. The name is a string and appears to be Unicode (says it is in the edmx). I have a method GetGroup() and I pass in a name to search for. Debugging through the code, I already have a group named "Test" in my database. Once I pass in a group named "TEST" I expect it to return the "Test" which was already in the database. It for some reason, does not find the "Test" and thinks "TEST" doesn't exist. Here is my query, I cannot see why it does not work. Please help.

"name" is the passed in the group name. My .Equals seems to only work if the gr.Name and name are the exact same. If one character is capital in one of the two strings, then the .Equals doesn't work. I have tried to use InvariantCultureIgnoreCase, and that did not seem to help. In case someone asks, the MyLeagueId and LeagueId will always match, the database is setup so there can be a group in a different league id. I do not think this is the problem.

Group g = (from gr in this.DatabaseConnection.Groups
           where gr.Name.Equals(name, StringComparison.OrdinalIgnoreCase) &&
           gr.LeagueId == this.MyLeagueId
           select gr).FirstOrDefault();

Upvotes: 48

Views: 53044

Answers (7)

Travyguy9
Travyguy9

Reputation: 4344

When using LINQ to Entities, it will automatically convert LINQ into SQL. And if the database field you are doing a .Equals on does not have a collate of NOCASE (SQLite in my example) then it will always be case-sensitive. In otherwords, the database defines how to do the string comparison rather than code.

Upvotes: 46

Muhammad Bilal
Muhammad Bilal

Reputation: 11

Try this!

EF.Functions.Collate(gr.Name, "SQL_Latin1_General_CP1_CI_AS") == name

Upvotes: 0

Swapnil Malap
Swapnil Malap

Reputation: 620

The string comparison with StringComparison.OrdinalIgnoreCase works in memory or with IEnumerable<T>. You are trying to use it with IQueryable<T>, but the provider of your queryable does not understand it.

This works for me:

db.Users.FirstOrDefault(
     s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase)
);

Upvotes: 48

Jowen
Jowen

Reputation: 5383

Use the String.Compare() as it can be translated to Sql.

Here are some examples of string matching in Linq, with the Sql translation as well.

Upvotes: 15

Viv
Viv

Reputation: 2595

Try name.Equals(gr.Name, StringComparison.OrdinalIgnoreCase)

If it works then the problem could be with gr.Name.

--- Edit ---

I'm guessing that gr.Name is not of type System.string. (since String.Equals gives you an error ==> from the previous post)

give this a shot

(gr.Name as string).Equals(name, StringComparison.OrdinalIgnoreCase)

or

String.Equals((gr.Name as string), name, StringComparison.OrdinalIgnoreCase)

Upvotes: 2

AlvinfromDiaspar
AlvinfromDiaspar

Reputation: 6822

I like TravyGuy's answer from a technical perspective. For a more direct, practical answer, try using:

string.Compare(string A, string B, StringComparison.OrdinalIgnoreCase) == 0

Upvotes: 6

xanatos
xanatos

Reputation: 111810

Made some research. You can't do. The collation (the type of comparison) is defined at the column level of the table. You can't modify it through EF. If it's defined as case insensitive, then all the searches will be case-insensitive. If it's defined as case sensitive, then your only hope is ToUpper() the strings.

http://connect.microsoft.com/VisualStudio/feedback/details/435783/entity-framework-conceptual-model-doesnt-support-string-equals-via-linq

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/3810aa67-f6fe-4624-a14b-eaaa0e05ddcd

EF4 Linq Oracle11g making queries none case-sensitive

LINQ to Entities case sensitive comparison

Upvotes: 10

Related Questions