忽略联接实体的全局查询过滤器

时间:2020-08-02 12:42:06

标签: c# linq asp.net-core entity-framework-core

在实现租户和软删除功能时,全局查询过滤器非常方便。

但是我的问题是,例如,当我编写带有联接的查询时

dbContext
    .entity1
    .Include("entity2.entity3.entity4")
    .Where(something)
    .select(something)
    .toList();

并且这些实体中的每个实体都有全局过滤器,然后在生成的SQL中,我为每个JOIN获得一个完整的子查询,在其中选择该实体的所有字段并检查全局过滤器。

但是我不想要那个。我希望全局过滤器仅应用于查询的根实体(entity1),而所有其他实体也可以正常加入。

实体之间的关系是:

  • 1个实体4-> N个实体3
  • 1实体3-> N实体2
  • 1实体2-> N实体1

在我的情况下,每个实体都获得其“承租人”字段集,并且在软删除实体时,该软删除将级联到其所有子级和子级。 因此,检查每个联接的这些字段完全是浪费时间。

1 个答案:

答案 0 :(得分:0)

目前您不能忽略Include中的查询过滤器。 EF Core回购中有an issue关于改进查询过滤器的信息,但不会纳入EF Core 5。

一种可能有用的方法是运行多个查询,并依靠EF Core的关系修正功能将事物连接在一起(我在文章EF Core In depth – what happens when EF Core reads from the database?中解释了关系修正)。

这里是执行两个查询的示例,其中关系修正将结合在一起。

var mainEntities = dbContext.entity1
   .Where(something)
   .Select(something) //But must contain the ent1 primary key, e.g. Id
   .ToList();
var ent2list = dbContext.entity2.IgnoreQueryFilters()
   .Include("entity3.entity4")
   .Where(ent2 => mainEntities.Select(ent1 => ent1.Id).Contains(ent2.Id)
   .ToList();

在该EF Core的关系修正结束时,将在相应的entity1实例中填充entity2导航属性。注意:如果使用AsNoTracking,则关系修正不起作用。