Mar*_*ndl 2 .net c# entity-framework entity-framework-core .net-core
我尝试在OnModelCreating方法(Entity Framework Core)中为具有ClientId属性(int)的所有实体应用查询过滤器。到目前为止,我能够过滤实体,但我很难为这些实体调用 HasQueryFilter。
过滤器应将ClientId当前实体的属性与名为 的服务的属性进行比较ITenantProvider。
这是我手动执行的方法:
modelBuilder.Entity<MyEntity>().HasQueryFilter(a => a.ClientId == _tenantProvider.TenantId);
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有 Generic 的 EF CoreHasQueryFilter方法采用LambdaExpression:
public virtual EntityTypeBuilder HasQueryFilter([CanBeNullAttribute] LambdaExpression filter);
Run Code Online (Sandbox Code Playgroud)
我不知道如何将上述调用转换为 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;
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上适用于第一次调用,但由于我使用Expression.Constant它,如果发生更改,它不适用于下一个请求_tenantProvider.TenantId。
如何在运行时比较实体ClientId属性_tenantProvider.TenantId?
获得相当于的运行时表达式的最简单方法
_tenantProvider.TenantId
Run Code Online (Sandbox Code Playgroud)
是构建一个编译时无参数 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);
Run Code Online (Sandbox Code Playgroud)