Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to order by 1 expression or 2 expressions based on a condition?

I am displaying businesses and people in a single result and would like to order them together.

Pseudocode:

if business name is not null
order by business name
else
order by first name then last name

I have LINQ query constructed which joins to several tables (and works fine) and looks roughly as follows.

var query = from x in ...
    join business in dbContext.Businesses on ...
    from businesses in bus.DefaultIfEmpty()
    join person in dbContext.People on ...
    from people in peo.DefaultIfEmpty()
    select new Party
    {
        person.FirstName,
        person.LastName,
        business.Name,
    };

I cannot work out how to write a LINQ expression which orders by ONLY business name if the record is a business, else person first name and last name. The closest I can get is the following, which always includes ordering by person last name (even for businesses).

var result =
    whereQuery
        .OrderBy(x => x.BusinessName != null ? x.BusinessName : x.PersonFirstName)
        .ThenBy(x => x.PersonLastName);

Which converts to SQL:

ORDER BY CASE
    WHEN [business].[Name] IS NOT NULL
    THEN [business].[Name]
    ELSE [person].[FirstName]
END, [person].[LastName]

What I would like is:

ORDER BY CASE
    WHEN [business].[Name] IS NOT NULL
    THEN [business].[Name]
    ELSE [person].[FirstName], [person].[LastName]
END

This is what I'd like to be able to write (obviously is not correct syntax for the false part):

var result =
        whereQuery
            .OrderBy(x => x.BusinessName != null ? x.BusinessName : x.PersonFirstName, x.PersonLastName);

Technically, it does not make too much difference (if it's a business, person first name and last name will be null, so the order should not be affected). But the SQL will still be trying to order by something which it doesn't need to do.

like image 966
David Spence Avatar asked Mar 07 '23 08:03

David Spence


1 Answers

var result =
  whereQuery
    .OrderBy(x => x.BusinessName != null ? x.BusinessName : x.PersonFirstName)
    .ThenBy(x => x.BusinessName != null ? x.BusinessName : x.PersonLastName);

There'll be a redundant second ordering in the case where BusinessName isn't null, but the query analyser (the next step after parsing the SQL) should be able to remove that redundancy.

like image 145
Jon Hanna Avatar answered Mar 25 '23 16:03

Jon Hanna