wtm 框架添加多租户


using System;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using BaseProj.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.DependencyInjection;
using NPOI.POIFS.FileSystem;
using WalkingTec.Mvvm.Core;

namespace BaseProj
{
public class DataContext : FrameworkContext
{
public DbSet<FrameworkUser> FrameworkUsers { get; set; }
public DbSet<Park> Parks { get; set; }

IServiceProvider services = null;
WTMContext wtm = null;

private void BuilderService()
{
services = Startup.AppServiceCollection?.BuildServiceProvider();
wtm = services?.GetService<WTMContext>();
}

public DataContext(CS cs)
: base(cs)
{
BuilderService();
}

public DataContext(string cs, DBTypeEnum dbtype)
: base(cs, dbtype)
{
BuilderService();
}

public DataContext(string cs, DBTypeEnum dbtype, string version = null)
: base(cs, dbtype, version)
{
BuilderService();
}

public string GetTenantCode()
{
return wtm?.LoginUserInfo?.TenantCode;
}

public bool IsSuperAdmin()
{
return wtm?.LoginUserInfo?.ITCode == "admin";
}

private void UpdateTenandCode()
{
// 获取所有新增、更新、删除的实体
var entities = ChangeTracker.Entries().Where(u => u.State == EntityState.Added || u.State == EntityState.Modified || u.State == EntityState.Deleted);

foreach (var entity in entities)
{
if (typeof(ITenants).IsAssignableFrom(entity.Entity.GetType()))
{
switch (entity.State)
{
// 自动设置租户Id
case EntityState.Added:
entity.Property(nameof(ITenants.TenantCode)).CurrentValue = GetTenantCode();
break;
// 排除租户Id
case EntityState.Modified:
entity.Property(nameof(ITenants.TenantCode)).IsModified = false;
break;
// 删除处理
case EntityState.Deleted:
break;
}
}
}
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(t => !t.Name.Contains("_View") && t.GetInterfaces().Contains(typeof(ITenants))))
.ToArray();
foreach (var type in types)
{
var entityBuilder = modelBuilder.Entity(type);
entityBuilder.HasQueryFilter(BuildTenantQueryFilter(entityBuilder));
}
}

protected virtual LambdaExpression BuildTenantQueryFilter(EntityTypeBuilder entityBuilder)
{

var metadata = entityBuilder.Metadata;
if (metadata.FindProperty(nameof(ITenants.TenantCode)) == null) return default;
var parameter = Expression.Parameter(metadata.ClrType, "u");
var properyName = Expression.Constant(nameof(ITenants.TenantCode));
var propertyValue = Expression.Call(Expression.Constant(this), this.GetType().GetMethod(nameof(this.GetTenantCode)));
var isAdmin = Expression.Call(Expression.Constant(this), this.GetType().GetMethod(nameof(this.IsSuperAdmin)));
var isEqual = Expression.Equal(Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(object) }, parameter, properyName), propertyValue);
var expressionBody = Expression.Or(isAdmin, isEqual);
var expression = Expression.Lambda(expressionBody, parameter);
return expression;
}

public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
UpdateTenandCode();
return base.SaveChanges(acceptAllChangesOnSuccess);
}

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
UpdateTenandCode();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

public DataContext(DbContextOptions<DataContext> options) : base(options) { }

public override async Task<bool> DataInit(object allModules, bool IsSpa)
{
var state = await base.DataInit(allModules, IsSpa);
bool emptydb = false;
try
{
emptydb = Set<FrameworkUser>().Count() == 0 && Set<FrameworkUserRole>().Count() == 0;
}
catch { }
if (state == true || emptydb == true)
{
//when state is true, means it's the first time EF create database, do data init here
//当state是true的时候,表示这是第一次创建数据库,可以在这里进行数据初始化
var user = new FrameworkUser
{
ITCode = "admin",
Password = Utils.GetMD5String("000000"),
IsValid = true,
Name = "Admin"
};

var userrole = new FrameworkUserRole
{
UserCode = user.ITCode,
RoleCode = "001"
};

Set<FrameworkUser>().Add(user);
Set<FrameworkUserRole>().Add(userrole);
await SaveChangesAsync();
}
return state;
}

}

/// <summary>
/// DesignTimeFactory for EF Migration, use your full connection string,
/// EF will find this class and use the connection defined here to run Add-Migration and Update-Database
/// </summary>
public class DataContextFactory : IDesignTimeDbContextFactory<DataContext>
{
public DataContext CreateDbContext(string[] args)
{
return new DataContext("Server=(localdb)\\mssqllocaldb;Database=DZHProj_db;Trusted_Connection=True;", DBTypeEnum.SqlServer);
}
}

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM