I want to achieve two things.
First, I want this join to be case insensitive.
I have used this case insensitive where clause in the past
where b.foo.Equals(foo, StringComparison.OrdinalIgnoreCase)
but I dont now, how to use it in join.
Second, I would like to return tuple with authors name and count of their books.
var query = from b in Books
join a in authors on b.Author equals a
select Tuple.Create(a, _count_of_authors_books_);
return query;
Thanks.
Linq does support joining with a case insensitive match, but just not in query syntax. You need to use Method Syntax.
Linq only supports equi-joins, but you can convert each operand to one case or the other: Note that this can have some interesting results in some cultures; if that's a concern, then another less-performant way would be to do a cross-join with an equality filter:
This can be accomplished by explicitly specifying a collation within the query itself: This generates a COLLATE clause in the SQL query, which applies a case-sensitive collation regardless of the collation defined at the column or database level: SELECT [c]. [Id], [c]. [Name] FROM [Customers] AS [c] WHERE [c].
The remote MSSQL database is set to collation: Finnish_Swedish_CI_AS, which means it's case insensitive? The local database is an auto-generated localDB with the property "Case Sensitive" set to False. No matter which of these two databases I use it's still always Case Sensitive for the users.
Linq does support joining with a case insensitive match, but just not in query syntax. You need to use Method Syntax.
var query = Books.Join(
authors, // the other list
book => book.Author, // what to compare in "Books"
author => author, // what to compare in "authors"
(book, author) => Tuple.Create(author, _count_of_authors_books_), // what to select at the end
StringComparer.InvariantCultureIgnoreCase); // how to do the comparison
StringComparer
has some other variations, use the one you need.
Linq only supports equi-joins, but you can convert each operand to one case or the other:
var query = from b in Books
join a in authors on b.Author.ToLower() equals a.ToLower()
select Tuple.Create(a, _count_of_authors_books_);
return query;
Note that this can have some interesting results in some cultures; if that's a concern, then another less-performant way would be to do a cross-join with an equality filter:
var query = from b in Books
from a in authors
where String.Compare(b.Author, a, true) == 0
select Tuple.Create(a, _count_of_authors_books_);
return query;
A little late to answering this, but according to the documentation on OrdinalIgnoreCase:
TheStringComparer returned by the OrdinalIgnoreCase property treats the characters in the strings to compare as if they were converted to uppercase using the conventions of the invariant culture, and then performs a simple byte comparison that is independent of language.
Then this would be the equivalent join:
var query = from b in Books
join a in authors on b.Author.ToUpperInvariant() equals a.ToUpperInvariant()
select Tuple.Create(a, _count_of_authors_books_);
return query;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With