Linq2db:查询对象层次结构的有效方法
Linq2db: effective way to query hierarchy of objects
我正在使用 c# 和 linq2db 并具有以下 class/tables 层次结构:
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>();
}
我想使用 where 语句从数据库中获取特定年份,但我想为它获取所有嵌套的 MonthlyTemplates,以及每个 Monthlytemplate 的所有 DailyTemplates。
我怎样才能有效地使用 linq2db 来做到这一点?
我想我应该使用 group by,但它只适用于一层深度。
没什么特别的。就像在 EF Core 中一样,linq2db 包含用于预加载的方法。
首先你必须定义 Associations
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;}
}
并查询
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();
或使用过滤器(如何自定义两种方式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();
或者您可以使用自定义投影,这样可以提高性能,因为您可以只选择需要的字段:
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();
我正在使用 c# 和 linq2db 并具有以下 class/tables 层次结构:
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>();
}
我想使用 where 语句从数据库中获取特定年份,但我想为它获取所有嵌套的 MonthlyTemplates,以及每个 Monthlytemplate 的所有 DailyTemplates。 我怎样才能有效地使用 linq2db 来做到这一点? 我想我应该使用 group by,但它只适用于一层深度。
没什么特别的。就像在 EF Core 中一样,linq2db 包含用于预加载的方法。 首先你必须定义 Associations
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;}
}
并查询
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();
或使用过滤器(如何自定义两种方式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();
或者您可以使用自定义投影,这样可以提高性能,因为您可以只选择需要的字段:
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();