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