Sort collection by first item of sub list in Entity Framework

前端 未结 2 738
星月不相逢
星月不相逢 2021-01-14 04:18

Is it possible to sort IQueryable collection by it\'s sub collections?

For example I have a Books collection. I also have an Authors<

相关标签:
2条回答
  • 2021-01-14 04:55

    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; }
        }
    }
    
    0 讨论(0)
  • 2021-01-14 05:10

    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
    
    0 讨论(0)
提交回复
热议问题