OnModelCreating。这是一个问题,因为每个请求都设置了租户ID。
每次创建dbcontext的新实例时,如何重新配置全局过滤器?
如果我不能使用全局过滤器,另一种方法是什么?
更新:
我需要提供一个带有e => e.TenantId == _tenantId
之类表达式的通用过滤器。我正在使用以下表达式:
var p = Expression.Parameter(type, "e");
Expression.Lambda(
Expression.Equal(
Expression.Property(p, tenantIdProperty.PropertyInfo),
Expression.Constant(_tenantId))
p);
由于该命令运行一次,因此_tenantId是固定的。因此,即使更新它,第一个值也会在linq表达式中捕获。
所以我的问题是,设置平等权利的正确方法是什么。
答案 0 :(得分:0)
此问题已通过以下正确的表达方式予以解决
Expression.MakeMemberAccess(
Expression.Constant(this, baseDbContextType),
baseDbContextType.GetProperty("TenantId")
我为所有数据库上下文使用基类。
GetProperty()
按原样工作是因为TenantId是公共财产。
答案 1 :(得分:0)
使用EF.Core,您实际上可以使用以下过滤器和语法
protected void OnModelCreating(ModelBuilder modelBuilder)
{
var entityConfiguration = modelBuilder.Entity<MyTenantAwareEntity>();
entityConfiguration.ToTable("my_table")
.HasQueryFilter(e => EF.Property<string>(e, "TenantId") == _tenantProvider.GetTenant())
[...]
_tenantProvider 是负责从HttpRequest中获取租户的类,可以使用HttpContextAccessor来实现。
答案 2 :(得分:0)
和.. 如果将其与软删除配合使用,则解决方法是: -对于ef core 3.1
internal static void AddQueryFilter<T>(this EntityTypeBuilder
entityTypeBuilder, Expression<Func<T, bool>> expression)
{
var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType);
var expressionFilter = ReplacingExpressionVisitor.Replace(
expression.Parameters.Single(), parameterType, expression.Body);
var currentQueryFilter = entityTypeBuilder.Metadata.GetQueryFilter();
if (currentQueryFilter != null)
{
var currentExpressionFilter = ReplacingExpressionVisitor.Replace(
currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body);
expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter);
}
var lambdaExpression = Expression.Lambda(expressionFilter, parameterType);
entityTypeBuilder.HasQueryFilter(lambdaExpression);
}
用法:
if (typeof(ITrackSoftDelete).IsAssignableFrom(entityType.ClrType))
modelBuilder.Entity(entityType.ClrType).AddQueryFilter<ITrackSoftDelete>(e => IsSoftDeleteFilterEnabled == false || e.IsDeleted == false);
if (typeof(ITrackTenant).IsAssignableFrom(entityType.ClrType))
modelBuilder.Entity(entityType.ClrType).AddQueryFilter<ITrackTenant>(e => e.TenantId == MyTenantId);