EfCore HasQueryFilter 方法 v2.2 中的奇怪行为 Expression<Func>(重构问题)

weird behavior Expression<Func> in EfCore HasQueryFilter method v2.2 (Refactoring problem)

我的 AppDbContext EfCore 2.2 中有一个 QueryFilter :

builder.Entity<MessageReceiver> ().HasQueryFilter (
    (q) => (q.ReciverId == _uai.LoggedInUserId) || 
           (q.Message.SenderId == _uai.LoggedInUserId));

此代码运行良好,因为我注入了自定义服务 (_uai) 以将登录用户信息检查到我的 AppDbContext 中。

   public class AppDbContext : DbContext {
      private readonly IUserAccessInfoService _uai;

      public AppDbContext (DbContextOptions<AppDbContext> options, IUserAccessInfoService userAccessInfo) : base (options) {
         _uai = userAccessInfo;
      }

但我无法重构此代码并将整个表达式移动到我的服务中! 将此代码重构为“_uai”服务后,我正在使用它:

builder.Entity<MessageReceiver> ().HasQueryFilter (_uai.GetMessageQueryFilter ());

在我的 'uai' 服务中,我重构了表达式:

// UserAccessInfoService ....

public Expression<Func<MessageReceiver, bool>> GetMessageQueryFilter () {
         return (q) =>
            (q.ReciverId == LoggedInUserId) || 
            (q.Message.SenderId == LoggedInUserId);
      }

// this way loggedInUser is null in runtime

表达式是否具有一些内联缓存功能?问题是当我重构这段代码时 EFCore 没有使用注入的服务值,重构后 LoggedInUserId 为 null。 我认为 efcore 对其表达式使用了某种缓存。

全局查询过滤器中使用的表达式是特殊的。特别是,它们仅被评估一次 除了 来自字段 属性 或 DbContext 方法的部分(如在您的原始代码中)。

这在 EF Core Global Query Fiters 文档示例中有部分解释:

Tip

Note the use of a DbContext instance level field: _tenantId used to set the current tenant. Model-level filters will use the value from the correct context instance (that is, the instance that is executing the query).

我希望他们在文档中更明确和明确地解释该行为,而不是作为示例的提示,因为这实际上是 唯一的方式 获得动态已评估过滤器。

话虽如此,请保持原始代码不变,或者使用不同的重构方式以备不时之需,以备不时之需 - interface/base class/ EF.Property 或手动表达式组合来绑定 ReceiverIdSenderId 表达式,但仍将它们与 this._uai.LoggedInUserId.

进行比较