/// <summary>
/// 实体
/// </summary>
public partial class ReadContext : BaseContext
{
private int _tenantId;
private int _accountId;
public ReadContext (DbContextOptions options, ITenantProvider tenantProvider, IAccountProvider accountProvider)
: base(options, tenantProvider)
{
_tenantId = tenantProvider.GetTenantId();
_accountId = accountProvider.GetAccountId();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
// 添加软删除过滤
if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType))
entityType.AddSoftDeleteQueryFilter();
// 添加租户过滤
if (typeof(IHasTenantId).IsAssignableFrom(entityType.ClrType))
entityType.AddTenantQueryFilter(_tenantId);
}
base.OnModelCreating(modelBuilder);
}
}
租户获取,登陆后是能获取得到的
/// <summary>
/// 租户提供者
/// </summary>
public class TenantProvider : ITenantProvider
{
private int _tenantId;
IHttpContextAccessor _accessor;
public TenantProvider(IHttpContextAccessor accessor)
{
_accessor = accessor;
}
public int GetTenantId()
{
if (_accessor.HttpContext != null)
{
int.TryParse(_accessor.HttpContext.Request.Headers["TenantId"], out _tenantId);
if (_tenantId == 0)
int.TryParse(_accessor.HttpContext.User.Claims.FirstOrDefault(m => m.Type == ClaimsName.TenantId)?.Value, out _tenantId);
}
//if (_tenantId == 0) return 1;
return _tenantId;
}
}
过滤相关代码
public static void AddTenantQueryFilter(this IMutableEntityType entityData, int tenantId)
{
var methodToCall = typeof(QueryFilterExtensions).GetMethod(nameof(GetTenantFilter), BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(entityData.ClrType);
var filter = methodToCall.Invoke(nameof(GetTenantFilter), new object[] { tenantId });
entityData.SetQueryFilter((LambdaExpression)filter);
}
private static LambdaExpression GetTenantFilter<TEntity>(int tenantId) where TEntity : class, IHasTenantId
{
Expression<Func<TEntity, bool>> filter = x => x.TenantId == tenantId;
return filter;
}
现在的方式是在执行OnModelCreating的时候配置,但是貌似不能根据登陆时候租户进行过滤,我看了下abp的,也是类似于这样,但是不懂他那个具体做了什么处理。
但是又一个问题,登录的时候header头里面没有租户id
用户选择后时是可以放到请求头的吧,也可以放到登录模型,登录后过滤直接用存用户信息中记录的那个就得了。