Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq case insensitive join

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.

like image 418
rluks Avatar asked Apr 13 '15 18:04

rluks


People also ask

Does LINQ support case-insensitive match?

Linq does support joining with a case insensitive match, but just not in query syntax. You need to use Method Syntax.

Does LINQ support cross-joins?

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:

How do I create a case-sensitive collation in a SQL query?

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].

Is the remote MSSQL database case insensitive?

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.


3 Answers

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.

like image 137
gunr2171 Avatar answered Oct 24 '22 03:10

gunr2171


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;
like image 44
D Stanley Avatar answered Oct 24 '22 01:10

D Stanley


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;
like image 39
Joe the Coder Avatar answered Oct 24 '22 01:10

Joe the Coder