【问题标题】:EF Core: Order By of nested eager-loaded collectionEF Core:嵌套预加载集合的排序依据
【发布时间】:2018-12-27 21:04:37
【问题描述】:

我有一个具有深度嵌套类层次结构的用例,例如:

public class Parent
{
    public int Id { get; set; }

    public List<ChildOne> Children { get; set; }
}


public class ChildOne
{
    public int Id { get; set; }
    public int ParentId { get; set; }

    public List<ChildTwo> ChildrenTwo { get; set; }
}


public class ChildTwo
{
    public int Id { get; set; }
    public int Priority { get; set; }

    public int ChildOneId { get; set; }

    public List<ChildThree> ChildrenThree { get; set; }
}


public class ChildThree
{
    public int Id { get; set; }

    public int ChildTwoId { get; set; }
}

如果我想加载所有父对象及其相关的子级别,我会这样做:

var objects = context.Parent
    .Include(parent => parent.Children)
        .ThenInclude(childOne => childOne.ChildrenTwo)
            .ThenInclude(childTwo => childTwo.ChildrenThree)
    .ToList();

但是,如果我希望 ChildOne 的即时加载导航属性中的 ChildrenTwo 实体按其 Priority 排序怎么办?我已经做了一些研究,从下面的链接(和其他一些链接)来看,显然在 EF Core 中还不能直接实现:

那么,您如何以一种快速的良好/干净的方式实现上述ChildrenTwo(由Priority)的排序?这可能意味着大部分工作应该发生在 DB 服务器上,而不是 .NET 客户端。这里最好的方法是什么?

【问题讨论】:

  • 仅通过将 (select new { ... }) 投影到 DTO 或原始实体类,在必要的 LINQ 语句中应用排序。
  • @GertArnold 感谢您的回复。我不确定我是否完全理解 - 你能举个例子吗?

标签: c# entity-framework-core


【解决方案1】:

虽然现在回答很晚,但它可能对未来的读者有所帮助:

我会解释代码:

var authorArticles = await _context.AuthorArticles
                .Include(a => a.Author)
                .ThenInclude(p => p.Person)
                .ThenInclude(pq => pq.Qualifications)
                .ThenInclude(q => q.QualificationSubject)
                .Include(a => a.Author)
                .ThenInclude(p => p.Person)
                .ThenInclude(pp => pp.Professions)
                .Include(a => a.Author)
                .ThenInclude(p => p.Person)
                .ThenInclude(pp => pp.Professions)
                .ThenInclude(prof => prof.Profession)
                .Where(aa => aa.ArticleId == articleId)
                .Select(s => new AuthorArticle
                {
                    Author = new Author
                    {
                        Affiliation = s.Author.Affiliation,
                        AvailableAsReviewer = s.Author.AvailableAsReviewer,
                        Person = new Person
                        {
                            Email = s.Author.Person.Email,
                            FirstName = s.Author.Person.FirstName,
                            LastName = s.Author.Person.LastName,
                            MiddleName = s.Author.Person.MiddleName,
                            Title = s.Author.Person.Title,
                            FullName = s.Author.Person.FullName,
                            UserId = s.Author.Person.UserId,
                            Professions = new Collection<PersonProfession>
                            {
                                new PersonProfession
                                {
                                    // using sorting here!!
                                    Organization = s.Author.Person.Professions
                                        .OrderByDescending(pid => pid.ProfessionId)
                                        .FirstOrDefault().Organization,
                                    Profession = s.Author.Person.Professions
                                        .OrderByDescending(pid => pid.ProfessionId)
                                        .FirstOrDefault().Profession
                                }
                            },
                            Qualifications = new Collection<PersonQualification>
                            {
                                new PersonQualification
                                {
                                    QualificationSubject = s.Author.Person.Qualifications
                                        .OrderByDescending(q => q.QualificationLevelId)
                                        .FirstOrDefault().QualificationSubject,
                                    QualificationLevelId = s.Author.Person.Qualifications
                                        .OrderByDescending(q => q.QualificationLevelId)
                                        .FirstOrDefault().QualificationLevelId
                                }
                            }
                        }
                    },
                    IsCorresponding = s.IsCorresponding,
                    AuthorPosition = s.AuthorPosition
                }).ToListAsync();

            return authorArticles;

如果您只是预先加载实体,那么在投影时;这意味着当您从查询中选择项目时,您可以以稍微不同的方式重新创建已经提供的对象。就我而言,我只想要一个人的职业,而这个人的资格也是如此。

帮助从Another SO great answer!中选择

【讨论】:

    猜你喜欢
    • 2019-04-27
    • 1970-01-01
    • 2022-06-10
    • 2018-11-06
    • 2021-01-26
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多