使用EF Core通过多个嵌套对象关系进行筛选



我有一个新的要求,即根据黑名单过滤查询返回的报告。

因此,最初我有一个查询,它会返回所需的所有相关信息,并获得与该特定用户相关的报告列表。

var reports = from r in Context.Reports
join ax in Context.AuthorizationXref on r.Id equals ax.ReportId
join g in Context.Groups on ax.GroupId equals g.Id
join ugx in Context.UsersGroupsXref on g.Id equals ugx.GroupId
where ugx.UserId == id
select r;

AuthorizationXref具有ReportID和GroupId。

public partial class AuthorizationXref
{
public int Id { get; set; }
public int ReportId { get; set; }
public int GroupId { get; set; }
public virtual Groups Group { get; set; }
public virtual Reports Report { get; set; }
}
public partial class Groups
{
public Groups()
{
AuthorizationXref = new HashSet<AuthorizationXref>();
UsersGroupsXref = new HashSet<UsersGroupsXref>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<AuthorizationXref> AuthorizationXref { get; set; }
public virtual ICollection<UsersGroupsXref> UsersGroupsXref { get; set; }
}

用户多对多组多对多报告(多对多是通过XREF完成的(。

在这里,我已经将其固定在700毫秒,这似乎真的很慢,我意识到我至少对数据库进行了4次点击,所以我尝试这样做,这或多或少相当于相同的数据,但速度快了约7倍:

var repo = context.Reports
.Include(x => x.AuthorizationXref)
.ThenInclude(x => x.Group)
.ThenInclude(x => x.UsersGroupsXref)
.ToList();

这大约是100毫秒,但没有对userId进行任何过滤。这些基准测试在Dev中,随着我们进入越来越多的报告添加到用户的更高环境,这些基准测试只会恶化。我知道使用Selects更有效,但我找不到实体上复杂嵌套多对多选择的示例。

我可以走到这一步,但不知道把额外的步骤放在哪里,以便深入对象。

var asdf = repo.Where(x=>x.AuthorizationXref.Any(y=>y.ReportId==x.Id));

最终目标是我需要一个按用户ID列出的报告列表,删除那些按ID显示在另一个表上的报告。所以有一个名为UserReportFilter的表,它有ReportId和UserId,该表中的任何报告都不应该出现在我的最终结果中。

顺便说一句,如果有人能给我指一个关于如何使用表达式的教程的方向(最好是一个不认为读者完全了解所有内容的教程(,我将不胜感激。我偶然看到了这篇文章,这似乎是一件很有力的事情,但我需要更多的解释。我理解这个概念,我使用了基本的Func返回进行查询,但没有那么广泛。

我假设您在Reports和UserReportFilter表之间有关系,因为您在UserReportFilter表格中有ReportId。下面的表达式应该有效,

var reports = context.Reports
.Include(x => x.AuthorizationXref)
.ThenInclude(x => x.Group)
.ThenInclude(x => x.UsersGroupsXref)
.Include(x => x.UserReportFilters)
.Where(x => x.AuthorizationXref.Any(y => y.Group.UsersGroupsXref.Any(z => z.UserId==id))
.ToList();

最新更新