Linq2db:查询对象层次结构的有效方法

Gri*_*dko 4 c# postgresql linq2db

我使用 ac# 和 linq2db 并具有以下类/表层次结构:

public class YearlyTemplate
{
    [Column]
    public int Id { get; set; }
    public List<MonthlyTemplate> MonthlyTemplates { get; set;}
}

public class MonthlyTemplate
{
    [Column]
    public int Id { get; set; }

    [Column]
    public int YearlyTemplateId { get; set; }

    public YearlyTemplate YearlyTemplate{ get; set; }

    public List<DailyTemplate> DailyTemplates { get; set;}
}

public class DailyTemplate
{
    [Column]
    public int Id { get; set; }

    [Column]
    public int MonthlyTemplateId { get; set; }
    
    public MonthlyTemplate MonthlyTemplate { get; set; }
}

public class AppDataConnect : DataConnection
{
    public ITable<YearlyTemplate> YearlyTemplates => GetTable<YearlyTemplate>();
    public ITable<WeeklyTemplate> WeeklyTemplates => GetTable<WeeklyTemplate>();
    public ITable<DailyTemplate>  DailyTemplates => GetTable<DailyTemplate>();
}

Run Code Online (Sandbox Code Playgroud)

我想使用 where 语句从数据库中获取特定年份,但我想获取它的所有嵌套 MonthlyTemplates,以及每个 Monthlytemplate 的所有 DailyTemplates。如何有效地使用 linq2db 来做到这一点?我想我应该使用 group by,但它仅适用于一层深度。

Svy*_*liv 8

这里没什么特别的。就像在 EF Core 中一样,linq2db 包含预加载方法。首先你必须定义关联

public class YearlyTemplate
{
    [Column]
    public int Id { get; set; }

    [Association(ThisKey = nameof(YearlyTemplate.Id), OtherKey = nameof(MonthlyTemplate.YearlyTemplateId))]
    public List<MonthlyTemplate> MonthlyTemplates { get; set;}
}

public class MonthlyTemplate
{
    [Column]
    public int Id { get; set; }

    [Column]
    public int YearlyTemplateId { get; set; }

    public YearlyTemplate YearlyTemplate{ get; set; }

    [Association(ThisKey = nameof(MonthlyTemplate.Id), OtherKey = nameof(DailyTemplate.MonthlyTemplateId))]
    public List<DailyTemplate> DailyTemplates { get; set;}
}
Run Code Online (Sandbox Code Playgroud)

并查询

var query = 
  from y in db.YearlyTemplates
           .LoadWith(yt => yt.MonthlyTemplates)
              .ThenLoad(mt => mt.DailyTemplates)
  where y.Id == 1
  select y;

var result = query.ToArray();
Run Code Online (Sandbox Code Playgroud)

或者使用过滤器(两种方式如何自定义LoadWith/ThenLoad)

var query = 
  from y in db.YearlyTemplates
           .LoadWith(yt => yt.MonthlyTemplates.Where(mt => !mt.IsDeleted))
              .ThenLoad(mt => mt.DailyTemplates, q => q.Where(ti => !dt.IsDeleted))
  where y.Id == 1
  select y;

var result = query.ToArray();
Run Code Online (Sandbox Code Playgroud)

或者您可以使用自定义投影,这可以提高性能,因为您可以仅选择所需的字段:

var query = 
  from y in db.YearlyTemplates
  where y.Id == 1
  select new 
  {
     Id = y.Id,
     MonthlyTemplates = y.MonthlyTemplates.Select(mt => new {
        mt.Id,
        DailyTemplates = mt.DailyTemplates.ToArray()
     }).ToArray()
  };

var result = query.ToArray();
Run Code Online (Sandbox Code Playgroud)

  • 更新了带有过滤器的帖子。关于文档:需要志愿者。 (2认同)