【发布时间】:2020-08-27 14:30:36
【问题描述】:
我有一项新要求,即根据属于黑名单的内容过滤来自查询的报告返回。
所以最初我有这个查询,它会带回所需的所有相关信息并获取与该特定用户关联的报告列表。
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; }
}
用户多对多组多对多报告(多对多通过外部参照完成)。
在这里,我将其设置为 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));
最终目标是我需要按 userId 列出的报告列表,删除那些按 ID 显示在另一个表上的报告。所以有一个名为 UserReportFilter 的表,它有 ReportId 和 UserId,该表中的任何报告都不应该出现在我的最终结果中。
作为旁注,如果有人可以向我指出如何使用表达式的教程(最好是不假定读者完全了解所有内容的教程),我将不胜感激。我遇到了this article,学习这样的东西似乎很强大,但是我需要更多的解释。我理解这个概念,并且我使用基本的 Func 返回进行查询,但没有那么广泛。
【问题讨论】:
标签: c# entity-framework-core linq-to-entities