代码之家  ›  专栏  ›  技术社区  ›  Martin Brandl

C#创建一个比较两个成员属性的LambdaExpression(对于EF Core HasQueryFilter)

  •  1
  • Martin Brandl  · 技术社区  · 7 年前

    我尝试在 OnModelCreating ClientId 属性(int)。到目前为止,我能够过滤实体,但我很难为这些实体调用HasQueryFilter。

    过滤器应比较 客户 ITenantProvider .

    以下是我手动操作的方式:

    modelBuilder.Entity<MyEntity>().HasQueryFilter(a => a.ClientId == _tenantProvider.TenantId);
    

    不幸的是,EF核心 HasQueryFilter 不带泛型的方法采用 LambdaExpression :

    public virtual EntityTypeBuilder HasQueryFilter([CanBeNullAttribute] LambdaExpression filter);
    

    我不知道如何将上述调用转换为Lambda表达式。我当前的代码如下所示:

    foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(e =>
        e.GetProperties().Select(property => property.Name).Any(pName => pName.Equals("ClientId"))))
    {
        var clientId = entityType.FindProperty("ClientId");
        if (clientId != null && clientId.ClrType == typeof(int))
        {
            var parameter = Expression.Parameter(entityType.ClrType, "p");
            var filter = Expression.Lambda(Expression.Equal(Expression.Property(parameter, clientId.PropertyInfo), Expression.Constant(_tenantProvider.TenantId), parameter);
            entityType.QueryFilter = filter;
        }
    }
    

    这基本上适用于第一次通话,但由于我使用 Expression.Constant 如果 _tenantProvider.TenantId 变化。

    如何比较实体 客户 财产 _租户提供者 在运行时?

    2 回复  |  直到 7 年前
        1
  •  5
  •   Ivan Stoev    7 年前

    _tenantProvider.TenantId
    

    是构建一个编译时无参数lambda表达式并获取其 Body

    var parameter = Expression.Parameter(entityType.ClrType, "p");
    var left = Expression.Property(parameter, clientId.PropertyInfo);
    Expression<Func<int>> tenantId = () => _tenantProvider.TenantId;
    var right = tenantId.Body;
    var filter = Expression.Lambda(Expression.Equal(left, right), parameter);
    
        2
  •  1
  •   Ivaylo Stoev    7 年前

    假设TenantProvider的实例没有更改:

    Expression.Property(Expression.Constant(_tenantProvider),"TenantId");
    

    如果你在某个时候重新测试它,这将不再有效。

    假设您有一些提供tennant id的静态属性,那么您可以使用:

    Expression.MakeMemberAccess(null,typeof(TennantIdProvider).GetMember("CurrentId")[0]);
    
    推荐文章