C# 如何通过单个数据库调用在子集合上加载筛选的子集合?
我在C项目中有一个通用实体,它有一个信号集合C# 如何通过单个数据库调用在子集合上加载筛选的子集合?,c#,linq,entity-framework-core,C#,Linq,Entity Framework Core,我在C项目中有一个通用实体,它有一个信号集合 public class Entity { public int Id { get; private set; } public Guid GuidId { get; private set; } private readonly List<Signal> signals = new List<Signal>(); public IEnumerable<Signal> Signals
public class Entity
{
public int Id { get; private set; }
public Guid GuidId { get; private set; }
private readonly List<Signal> signals = new List<Signal>();
public IEnumerable<Signal> Signals => this.signals.AsReadOnly();
}
我希望能够加载实体的信号和经过过滤的样本子集。目前我有以下几点:
/// <param name="guidId">entity id</param>
/// <param name="from">Beginning of the sample period</param>
/// <param name="to">End of the sample period</param>
/// <returns>Populated entity</returns>
public async Task<T> GetByGuidIdWithSignalsAsync(Guid guidId, DateTime from, DateTime to)
{
var entity = await this.DbContext.Set<T>()
.Include(s => s.Signals)
.SingleAsync(s => s.GuidId == guidId);
foreach (var signal in entity.Signals)
{
await this.DbContext.Entry(signal)
.Collection(s => s.Samples)
.Query()
.Where(s => s.TimeStamp >= from && s.TimeStamp <= to)
.LoadAsync();
}
return entity;
}
不幸的是,这需要为每个信号对数据库进行多次调用。它能被压缩成一个调用吗?我想你需要的是类似于下面的东西,如果没有确切的类结构,写这篇文章是相当困难的。但它应该给你一个起点,如果需要的话,很乐意帮助你进一步发展
var entity = await this.DbContext.Set<T>()
.Include(s => s.Signals)
.SingleAsync(s => s.GuidId == guidId)
.SelectMany(entity => entity.Signals
.Select(signal => signal.Samples)
.Where(sample => sample.TimeStamp >= from && s.TimeStamp <= to);
我认为您需要的是类似于下面的内容,如果没有确切的类结构,编写这篇文章是相当困难的。但它应该给你一个起点,如果需要的话,很乐意帮助你进一步发展
var entity = await this.DbContext.Set<T>()
.Include(s => s.Signals)
.SingleAsync(s => s.GuidId == guidId)
.SelectMany(entity => entity.Signals
.Select(signal => signal.Samples)
.Where(sample => sample.TimeStamp >= from && s.TimeStamp <= to);
我想如果你从样品开始,一切都会更容易。代码看起来像:
from row in _db.Samples
where row.Signal.Entity.TimeStamp == whatever
select row
我想如果你从样品开始,一切都会更容易。代码看起来像:
from row in _db.Samples
where row.Signal.Entity.TimeStamp == whatever
select row
免责声明:我是项目的所有者
EF+免费开放源码允许轻松筛选包含的实体
例如:
var entity = await this.DbContext.Set<T>()
.IncludeFilter(s => s.Signals)
.IncludeFilter(s => s.Signals.SelectMany(x => Samples.Where(sa => sa.TimeStamp >= from && sa.TimeStamp <= to)))
.SingleAsync(s => s.GuidId == guidId);
免责声明:我是项目的所有者
EF+免费开放源码允许轻松筛选包含的实体
例如:
var entity = await this.DbContext.Set<T>()
.IncludeFilter(s => s.Signals)
.IncludeFilter(s => s.Signals.SelectMany(x => Samples.Where(sa => sa.TimeStamp >= from && sa.TimeStamp <= to)))
.SingleAsync(s => s.GuidId == guidId);
太好了,午饭后我会把它换掉,然后告诉你,嗨@andyb952,它几乎成功了;-您的查询已收回所有样本,但没有将它们完全加载到本地缓存中。下面的答案只在一个查询中处理了一下……太好了,午饭后我会把它换掉,让你知道,嗨@andyb952,它几乎成功了;-您的查询已收回所有样本,但没有将它们完全加载到本地缓存中。下面的答案只是在一个查询中管理它…感谢Ivan的报告,页面已更新,下次重置时将可用。EF Core for version 2.x从上个月开始就受到支持。感谢Jonathon,我没有意识到IncludeFilter是开源库的一部分,我会尝试一下并对结果进行评论。感谢Ivan的报告,该页面已更新,将在下次重置时提供。2.x版的EF Core从上个月开始就得到了支持。感谢Jonathon,我没有意识到IncludeFilter是开源库的一部分,我会尝试一下并对结果进行评论。