簡體   English   中英

手動包含在 EF Core 中

[英]Manual Include in EF Core

我有以下結構: Training has many Module has many Phase has many Question

我使用以下查詢來獲取上述內容

Context.Trainings
       .Include(x => x.Modules)
       .ThenInclude(x => x.Phases)
       .ThenInclude(y => y.Questions)

Question也有很多Comment ,但這種關系沒有被定義為導航屬性,因為Comment可以有不同類型的專利。 所以Comment只有一個ParentId ,它有時是Question ,有時是其他東西。

我的問題是如何修改上述查詢,以對每個Question計算來自Context.Comments的子Comment並將其分配給Question.CommentCount 有點像手冊Include

在我的腦海里是這樣的

Context.Trainings
       .Include(x => x.Modules)
       .ThenInclude(x => x.Phases)
       .ThenInclude(y => y.Questions.Select(x=> new Question.Question {              
                Name = x.Name,
                Description = x.Description,                
                CommentCount = Context.Comments.Where(y=>y.ParentId == x.Id)                
            }));

但似乎您不能將預測放入Include中,我不知道如何以另一種方式考慮這一點。

隨着實體的建立,例如...

public class Training
{
    public int Id { get; set; }
    
    public ICollection<Module> Modules { get; set; }
}

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

    public ICollection<Phase> Phases { get; set; }
}

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

    public ICollection<Question> Questions { get; set; }
}

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

    [NotMapped]
    public int CommentCount { get; set; }
}

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

    public int ParentId { get; set; }
}

// DbContext
public DbSet<Training> Trainings { get; set; }
public DbSet<Module> Modules { get; set; }
public DbSet<Phase> Phases { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Comment> Comments { get; set; }

...它可以在一個查詢中完成,但它非常混亂。

// query all nested navigations using projections with extra data
var projected = await context.Trainings
    .Select(t => 
        new 
        { 
            Training = t, 
            Modules = t.Modules.Select(m => 
                new 
                { 
                    Module = m, 
                    Phases = m.Phases.Select(p => 
                        new 
                        { 
                            Phase = p, 
                            Questions = p.Questions.Select(q => 
                                new 
                                { 
                                    Question = q, 
                                    CommentCount = context.Comments.Count(c => c.ParentId == q.Id) 
                                }
                            )
                        }
                    )
                }
            )
        }
    )
    .ToListAsync();

// fixup by setting comment count from dto projection to "real" tracked entity
foreach (var q in projected.SelectMany(t => t.Modules).SelectMany(m => m.Phases).SelectMany(m => m.Questions))
{
    q.Question.CommentCount = q.CommentCount;
}

// thanks to ef core entity tracker this will still work
var trainings = projected.Select(p => p.Training);
var totalCommentCount = trainings.SelectMany(t => t.Modules).SelectMany(m => m.Phases).SelectMany(p => p.Questions).Sum(q => q.CommentCount);

最終查詢

SELECT [t].[Id], [t0].[Id], [t0].[TrainingId], [t0].[Id0], [t0].[ModuleId], [t0].[Id00], [t0].[PhaseId], [t0].[c]
      FROM [Trainings] AS [t]
      LEFT JOIN (
          SELECT [m].[Id], [m].[TrainingId], [t1].[Id] AS [Id0], [t1].[ModuleId], [t1].[Id0] AS [Id00], [t1].[PhaseId], [t1].[c]
          FROM [Modules] AS [m]
          LEFT JOIN (
              SELECT [p].[Id], [p].[ModuleId], [q].[Id] AS [Id0], [q].[PhaseId], (
                  SELECT COUNT(*)
                  FROM [Comments] AS [c]
                  WHERE [c].[ParentId] = [q].[Id]) AS [c]
              FROM [Phases] AS [p]
              LEFT JOIN [Questions] AS [q] ON [p].[Id] = [q].[PhaseId]
          ) AS [t1] ON [m].[Id] = [t1].[ModuleId]
      ) AS [t0] ON [t].[Id] = [t0].[TrainingId]
      ORDER BY [t].[Id], [t0].[Id], [t0].[Id0]

正如評論中所指出的,您可以從使用 TPH 和真正的導航集合返回問題評論中受益,並且您可能還應該使用拆分查詢或多個查詢,而不是像這樣將它們全部連接起來。 但根據用例,也許單個查詢對您來說可能會更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM