Is it possible to sort IQueryable
collection by it\'s sub collections?
For example I have a Books
collection. I also have an Authors<
Do you mean something like this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Book> books = new List<Book>() {
new Book() { name = "A", authors = new List<string>() { "AuthorA", "AuthorB","AuthorC"}},
new Book() { name = "B", authors = new List<string>() { "AuthorD", "AuthorE","AuthorF"}},
new Book() { name = "C", authors = new List<string>() { "AuthorG", "AuthorH","AuthorI"}},
new Book() { name = "D", authors = new List<string>() { "AuthorJ", "AuthorK","AuthorL"}},
new Book() { name = "E", authors = new List<string>() { "AuthorM", "AuthorN","AuthorO"}}
};
var orderedBook = books.OrderBy(x => x.authors.FirstOrDefault()).ToList();
}
}
public class Book
{
public string name { get; set; }
public List<string> authors { get; set; }
}
}
The answer to your concrete question (after clarification that The authors should be ordered by name, and the books collection by previously ordered list of authors) is like this:
var query = db.Books
.OrderBy(b => b.Authors.OrderBy(a => a.Name).Select(a => a.Name).FirstOrDefault());
which would generate a single SQL query like this:
SELECT
[Project2].[Id] AS [Id],
[Project2].[Title] AS [Title]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
(SELECT TOP (1) [Project1].[Name] AS [Name]
FROM ( SELECT
[Extent2].[Name] AS [Name]
FROM [dbo].[Author] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[BookId]
) AS [Project1]
ORDER BY [Project1].[Name] ASC) AS [C1]
FROM [dbo].[Book] AS [Extent1]
) AS [Project2]
ORDER BY [Project2].[C1] ASC
Note that the books w/o author will be the first in the order.
Another way is to use Min
function:
var query = db.Books
.OrderBy(b => b.Authors.Min(a => a.Name));
with SQL translation:
SELECT
[Project1].[Id] AS [Id],
[Project1].[Title] AS [Title]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
(SELECT
MIN([Extent2].[Name]) AS [A1]
FROM [dbo].[Author] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[BookId]) AS [C1]
FROM [dbo].[Book] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[C1] ASC