Question: C# IQueryable .Union reset sorting

I have the following code:
var expressions = new List<IQueryable<Container>>();

var containers1 = containers
    .Where(x => EF.Functions.Like(x.ContainerReference1, $"%{message.SearchValue}%")
             || EF.Functions.Like(x.ContainerReference2, $"%{message.SearchValue}%"))
    .OrderBy(x => x.ContainerReference1)
    .ThenBy(x => x.ContainerReference2)
    .ThenByDescending(x => x.DateUpdated);
expressions.Add(containers1);

var containers2 = containers
                  .Where(x => EF.Functions.Like(x.Description, $"%{message.SearchValue}%"))
                  .OrderBy(x => x.Description)
                  .ThenByDescending(x => x.DateUpdated);
expressions.Add(containers2);

var containers3 = containers.Where(x => x.ContactEmails
                            .OrderBy(y => y.Email)
                            .ThenBy(y => y.DisplayName)
                            .Any(y => EF.Functions.Like(y.Email, $"%{message.SearchValue}%")
                                 || EF.Functions.Like(y.DisplayName, $"%{message.SearchValue}%")))
                            .OrderByDescending(x => x.DateUpdated);
expressions.Add(containers3);

var containers4 = containers
                            .Where(x => EF.Functions.Like(x.Keywords, $"%{message.SearchValue}%"))
                            .OrderBy(x => x.Keywords)
                            .ThenByDescending(x => x.DateUpdated);
expressions.Add(containers4);

containers = expressions.Aggregate((acc, i) => acc.Union(i));

But after .Union operation sorting is reset.
How can I prevent resetting of sorting?


Answer:
Union operator does not preserve the order of the elements. You need to dynamically construct the sorting logic based on the presence of data
var expressions = new List<IQueryable<Container>>();
var sortingExpressions = new List<Func<IQueryable<Container>, IOrderedQueryable<Container>>>();

var containers1 = containers
        .Where(x => EF.Functions.Like(x.ContainerReference1, $"%{message.SearchValue}%")
                || EF.Functions.Like(x.ContainerReference2, $"%{message.SearchValue}%"));
if (containers1.Any())
{
    var containers1Sorting = new Func<IQueryable<Container>, IOrderedQueryable<Container>>(x => x
        .OrderBy(y => y.ContainerReference1)
        .ThenBy(y => y.ContainerReference2)
        .ThenByDescending(y => y.DateUpdated));

    expressions.Add(containers1);
    sortingExpressions.Add(containers1Sorting);
}

var containers2 = containers
          .Where(x => EF.Functions.Like(x.Description, $"%{message.SearchValue}%"));
if (containers2.Any())
{
    var containers2Sorting = new Func<IQueryable<Container>, IOrderedQueryable<Container>>(x => x
        .OrderBy(y => y.Description)
        .ThenByDescending(y => y.DateUpdated));

    expressions.Add(containers2);
    sortingExpressions.Add(containers2Sorting);
}

var containers3 = containers
        .Where(x => x.ContactEmails
            .Any(y => EF.Functions.Like(y.Email, $"%{message.SearchValue}%")
                || EF.Functions.Like(y.DisplayName, $"%{message.SearchValue}%")));
if (containers3.Any())
{
    var containers3Sorting = new Func<IQueryable<Container>, IOrderedQueryable<Container>>(x => x
        .OrderBy(y => y.ContactEmails.OrderBy(z => z.Email).ThenBy(z => z.DisplayName))
        .OrderByDescending(x => x.DateUpdated));

    expressions.Add(containers3);
    sortingExpressions.Add(containers3Sorting);
}

var containers4 = containers
      .Where(x => EF.Functions.Like(x.Keywords, $"%{message.SearchValue}%"));
if (containers4.Any())
{
    var containers4Sorting = new Func<IQueryable<Container>, IOrderedQueryable<Container>>(x => x
        .OrderBy(y => y.Keywords)
        .ThenByDescending(y => y.DateUpdated));

    expressions.Add(containers4);
    sortingExpressions.Add(containers4Sorting);
}

var mergedContainers = expressions.Aggregate((acc, i) => acc.Union(i));

if (sortingExpressions.Any())
{
    var mergedSorting = sortingExpressions
        .Aggregate((acc, next) => q => next(acc(q)));

    containers = mergedSorting(mergedContainers);
}
else
{
    containers = mergedContainers.OrderByDescending(x => x.DateUpdated);
}