From 2013aa5db82100be893492dd3d186811798d99af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com>
Date: Sun, 21 Jan 2024 18:11:04 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E5=A4=9A=E7=A7=9F?=
=?UTF-8?q?=E6=88=B7saas=E6=A1=86=E6=9E=B6=E6=90=AD=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Yi.Abp.Net8/Yi.Abp.sln | 2 +-
.../DbConnOptions.cs | 107 +++++++++++
.../ISqlSugarDbContext.cs | 2 +
.../IgnoreCodeFirstAttribute.cs | 13 ++
.../MasterTenantAttribute.cs | 13 ++
.../DbConnOptions.cs | 49 -----
.../SqlSugarDbContext.cs | 9 +-
.../UnitOfWorkSqlsugarDbContextProvider.cs | 82 ++++++---
.../YiFrameworkSqlSugarCoreModule.cs | 8 +-
.../SqlSugarTenantStore.cs | 28 +--
.../TenantAggregateRoot.cs | 10 +-
.../TenantManagementExtensions.cs | 18 ++
...i.Framework.TenantManagement.Domain.csproj | 3 +-
.../TenantConst.cs | 13 ++
...work.TenantManagement.Domain.Shared.csproj | 13 ++
...eworkTenantManagementDomainSharedModule.cs | 11 ++
.../MultiTenantConnectionStringResolver2.cs | 168 ------------------
Yi.Abp.Net8/src/Yi.Abp.Web/Program.cs | 4 -
Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 8 +-
19 files changed, 295 insertions(+), 266 deletions(-)
create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/IgnoreCodeFirstAttribute.cs
create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs
delete mode 100644 Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/DbConnOptions.cs
create mode 100644 Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantManagementExtensions.cs
create mode 100644 Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/TenantConst.cs
create mode 100644 Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/Yi.Framework.TenantManagement.Domain.Shared.csproj
create mode 100644 Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/YiFrameworkTenantManagementDomainSharedModule.cs
delete mode 100644 Yi.Abp.Net8/src/Yi.Abp.Web/MultiTenantConnectionStringResolver2.cs
diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln
index 9dcccd99..3791f61e 100644
--- a/Yi.Abp.Net8/Yi.Abp.sln
+++ b/Yi.Abp.Net8/Yi.Abp.sln
@@ -94,7 +94,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenant-management", "tenant
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.SqlSugarCore", "module\tenant-management\Yi.Framework.TenantManagement.SqlSugarCore\Yi.Framework.TenantManagement.SqlSugarCore.csproj", "{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.TenantManagement.Domain", "module\tenant-management\Yi.Framework.TenantManagement.Domain\Yi.Framework.TenantManagement.Domain.csproj", "{54D8E2BC-591C-4344-A58E-874D49C00B41}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Domain", "module\tenant-management\Yi.Framework.TenantManagement.Domain\Yi.Framework.TenantManagement.Domain.csproj", "{54D8E2BC-591C-4344-A58E-874D49C00B41}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
new file mode 100644
index 00000000..4aeb7766
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
@@ -0,0 +1,107 @@
+using SqlSugar;
+
+namespace Yi.Framework.SqlSugarCore.Abstractions
+{
+ public class DbConnOptions
+ {
+ ///
+ /// 连接字符串(如果开启多租户,也就是默认库了),必填
+ ///
+ public string? Url { get; set; }
+
+ ///
+ /// 数据库类型
+ ///
+ public DbType? DbType { get; set; }
+
+ ///
+ /// 开启种子数据
+ ///
+ public bool EnabledDbSeed { get; set; } = false;
+
+
+
+ ///
+ /// 开启codefirst
+ ///
+ public bool EnabledCodeFirst { get; set; } = false;
+
+ ///
+ /// 开启sql日志
+ ///
+ public bool EnabledSqlLog { get; set; } = true;
+
+ ///
+ /// 实体程序集
+ ///
+ public List? EntityAssembly { get; set; }
+
+ ///
+ /// 开启读写分离
+ ///
+ public bool EnabledReadWrite { get; set; } = false;
+
+ ///
+ /// 读写分离
+ ///
+ public List? ReadUrl { get; set; }
+
+ ///
+ /// 开启Saas多租户
+ ///
+ public bool EnabledSaasMultiTenancy { get; set; } = false;
+
+
+ ///
+ /// 默认租户库连接,如果不填,那就是默认库的地址
+ ///
+ public string? MasterSaasMultiTenancyUrl { get; set; }
+
+
+ ///
+ /// Saas租户连接
+ ///
+ public List? SaasMultiTenancy { get; set; }
+
+ public static string MasterTenantDbDefaultName = "Master";
+ public static string TenantDbDefaultName = "Default";
+
+ public SaasMultiTenancyOptions GetDefaultSaasMultiTenancy()
+ {
+ return new SaasMultiTenancyOptions { Name = TenantDbDefaultName, Url = Url };
+ }
+ public SaasMultiTenancyOptions? GetDefaultMasterSaasMultiTenancy()
+ {
+ if (EnabledSaasMultiTenancy == false)
+ {
+ return null;
+ }
+ if (string.IsNullOrEmpty(MasterSaasMultiTenancyUrl))
+ {
+
+ return new SaasMultiTenancyOptions { Name = MasterTenantDbDefaultName, Url = Url };
+ }
+ else
+ {
+ return new SaasMultiTenancyOptions()
+ {
+ Name = MasterTenantDbDefaultName,
+ Url = MasterSaasMultiTenancyUrl
+ };
+ }
+ }
+ }
+
+ public class SaasMultiTenancyOptions
+ {
+ ///
+ /// 租户名称标识
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 连接Url
+ ///
+ public string Url { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/ISqlSugarDbContext.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/ISqlSugarDbContext.cs
index eed39e76..8fc6afa5 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/ISqlSugarDbContext.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/ISqlSugarDbContext.cs
@@ -12,10 +12,12 @@ namespace Yi.Framework.SqlSugarCore.Abstractions
{
// IAbpLazyServiceProvider LazyServiceProvider { get; set; }
ISqlSugarClient SqlSugarClient { get; }
+ DbConnOptions Options { get; }
///
/// 数据库备份
///
void BackupDataBase();
+ void SetSqlSugarClient(ISqlSugarClient sqlSugarClient);
}
}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/IgnoreCodeFirstAttribute.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/IgnoreCodeFirstAttribute.cs
new file mode 100644
index 00000000..c7e11169
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/IgnoreCodeFirstAttribute.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.SqlSugarCore.Abstractions
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class IgnoreCodeFirstAttribute : Attribute
+ {
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs
new file mode 100644
index 00000000..fee1dee7
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.SqlSugarCore.Abstractions
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class MasterTenantAttribute : Attribute
+ {
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/DbConnOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/DbConnOptions.cs
deleted file mode 100644
index 4beaa57b..00000000
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/DbConnOptions.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using SqlSugar;
-
-namespace Yi.Framework.SqlSugarCore
-{
- public class DbConnOptions
- {
- ///
- /// 连接字符串,必填
- ///
- public string? Url { get; set; }
-
- ///
- /// 数据库类型
- ///
- public DbType? DbType { get; set; }
-
- ///
- /// 开启种子数据
- ///
- public bool EnabledDbSeed { get; set; } = false;
-
- ///
- /// 开启读写分离
- ///
- public bool EnabledReadWrite { get; set; } = false;
-
- ///
- /// 开启codefirst
- ///
- public bool EnabledCodeFirst { get; set; } = false;
-
- ///
- /// 开启sql日志
- ///
- public bool EnabledSqlLog { get; set; } = true;
-
- ///
- /// 实体程序集
- ///
- public List? EntityAssembly { get; set; }
-
- ///
- /// 读写分离
- ///
- public List? ReadUrl { get; set; }
-
-
- }
-}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
index 6418bd14..292c8662 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
@@ -22,7 +22,7 @@ namespace Yi.Framework.SqlSugarCore
///
/// SqlSugar 客户端
///
- public ISqlSugarClient SqlSugarClient { get; }
+ public ISqlSugarClient SqlSugarClient { get; private set; }
public ICurrentUser CurrentUser => LazyServiceProvider.GetRequiredService();
private IAbpLazyServiceProvider LazyServiceProvider { get; }
@@ -36,8 +36,13 @@ namespace Yi.Framework.SqlSugarCore
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled() ?? false;
public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance);
- protected DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService>().Value;
+ public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService>().Value;
+
+ public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient)
+ {
+ SqlSugarClient=sqlSugarClient;
+ }
public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider)
{
LazyServiceProvider = lazyServiceProvider;
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs
index 6d83cd70..af319ea8 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs
@@ -18,7 +18,7 @@ namespace Yi.Framework.SqlSugarCore.Uow
{
public class UnitOfWorkSqlsugarDbContextProvider : ISugarDbContextProvider where TDbContext : ISqlSugarDbContext
{
-
+ private readonly string MasterTenantDbDefaultName = DbConnOptions.MasterTenantDbDefaultName;
public ILogger> Logger { get; set; }
protected readonly IUnitOfWorkManager UnitOfWorkManager;
@@ -47,17 +47,12 @@ namespace Yi.Framework.SqlSugarCore.Uow
if (unitOfWork == null)
{
UnitOfWorkManager.Begin(true);
- unitOfWork=UnitOfWorkManager.Current;
+ unitOfWork = UnitOfWorkManager.Current;
//取消工作单元强制性
//throw new AbpException("A DbContext can only be created inside a unit of work!");
}
- //var sss= unitOfWork.ServiceProvider.GetRequiredService();
- //Console.WriteLine("反户的:"+sss.SqlSugarClient.ContextID);
- //return sss;
- ]
-
- var connectionStringName = "Default";
- var connectionString = await ResolveConnectionStringAsync(null);
+ var connectionStringName = ConnectionStrings.DefaultConnectionStringName;
+ var connectionString = await ResolveConnectionStringAsync(connectionStringName);
// var dbContextKey = $"{this.GetType().FullName}_{connectionString}";
var dbContextKey = "Default";
var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
@@ -77,12 +72,56 @@ namespace Yi.Framework.SqlSugarCore.Uow
protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork, string connectionStringName, string connectionString)
{
-
+
var dbContext = await CreateDbContextAsync(unitOfWork);
- // Console.WriteLine("111111:" + dbContext.SqlSugarClient.ContextID);
+
+ //没有检测到使用多租户功能,默认使用默认库即可
+ if (string.IsNullOrWhiteSpace(connectionString))
+ {
+ connectionString = dbContext.Options.Url;
+ connectionStringName = DbConnOptions.TenantDbDefaultName;
+ }
+
+ //获取到DB之后,对多租户多库进行处理
+ var changedDbContext = DatabaseChange(dbContext, connectionStringName, connectionString);
+
+
+ return changedDbContext;
+ }
+
+ protected virtual TDbContext DatabaseChange(TDbContext dbContext, string configId, string connectionString)
+ {
+ var dbOption = dbContext.Options;
+ var db = dbContext.SqlSugarClient.AsTenant();
+ //主库的Db切换,当操作的是租户表的时候
+ if (CurrentTenant.Name == MasterTenantDbDefaultName)
+ {
+ //直接切换
+ configId = MasterTenantDbDefaultName;
+ var conStrOrNull= dbOption.GetDefaultMasterSaasMultiTenancy();
+ Volo.Abp.Check.NotNull(conStrOrNull,"租户主库未找到");
+ connectionString = conStrOrNull.Url;
+ }
+
+ //租户Db的动态切换
+ //二级缓存
+ if (!db.IsAnyConnection(configId))
+ {
+ //添加一个db到当前上下文 (Add部分不线上下文不会共享)
+ db.AddConnection(new ConnectionConfig()
+ {
+ DbType = dbOption.DbType!.Value,
+ ConfigId = configId,//设置库的唯一标识
+ IsAutoCloseConnection = true,
+ ConnectionString = connectionString
+ });
+ }
+ var currentDb = db.GetConnection(configId) as ISqlSugarClient;
+ dbContext.SetSqlSugarClient(currentDb);
return dbContext;
}
+
protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork)
{
return unitOfWork.ServiceProvider.GetRequiredService();
@@ -92,22 +131,22 @@ namespace Yi.Framework.SqlSugarCore.Uow
}
protected virtual async Task CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
{
- var transactionApiKey = $"Sqlsugar_Default"+Guid.NewGuid().ToString();
+ var transactionApiKey = $"Sqlsugar_Default" + Guid.NewGuid().ToString();
var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as SqlSugarTransactionApi;
//if (activeTransaction==null|| activeTransaction.Equals(default(SqlSugarTransactionApi)))
//{
- var dbContext = unitOfWork.ServiceProvider.GetRequiredService();
- var transaction = new SqlSugarTransactionApi(
- dbContext
- );
- unitOfWork.AddTransactionApi(transactionApiKey, transaction);
+ var dbContext = unitOfWork.ServiceProvider.GetRequiredService();
+ var transaction = new SqlSugarTransactionApi(
+ dbContext
+ );
+ unitOfWork.AddTransactionApi(transactionApiKey, transaction);
- //await Console.Out.WriteLineAsync("开始新的事务");
- // Console.WriteLine(dbContext.SqlSugarClient.ContextID);
- await dbContext.SqlSugarClient.Ado.BeginTranAsync();
- return dbContext;
+ //await Console.Out.WriteLineAsync("开始新的事务");
+ // Console.WriteLine(dbContext.SqlSugarClient.ContextID);
+ await dbContext.SqlSugarClient.Ado.BeginTranAsync();
+ return dbContext;
//}
//else
//{
@@ -134,5 +173,6 @@ namespace Yi.Framework.SqlSugarCore.Uow
return await ConnectionStringResolver.ResolveAsync(connectionStringName);
}
+
}
}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/YiFrameworkSqlSugarCoreModule.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/YiFrameworkSqlSugarCoreModule.cs
index f7f1a81f..d4b1e02b 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/YiFrameworkSqlSugarCoreModule.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/YiFrameworkSqlSugarCoreModule.cs
@@ -51,6 +51,9 @@ namespace Yi.Framework.SqlSugarCore
var service = context.ServiceProvider;
var options = service.GetRequiredService>().Value;
+
+ //Todo:准备支持多租户种子数据及CodeFirst
+
if (options.EnabledCodeFirst)
{
CodeFirst(service);
@@ -73,7 +76,10 @@ namespace Yi.Framework.SqlSugarCore
List types = new List();
foreach (var module in moduleContainer.Modules)
{
- types.AddRange(module.Assembly.GetTypes().Where(x => x.GetCustomAttribute() != null).Where(x => x.GetCustomAttribute() is null));
+ types.AddRange(module.Assembly.GetTypes()
+ .Where(x => x.GetCustomAttribute() == null)
+ .Where(x => x.GetCustomAttribute() != null)
+ .Where(x => x.GetCustomAttribute() is null));
}
if (types.Count > 0)
{
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/SqlSugarTenantStore.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/SqlSugarTenantStore.cs
index c02bcd44..684be613 100644
--- a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/SqlSugarTenantStore.cs
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/SqlSugarTenantStore.cs
@@ -2,9 +2,7 @@
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Data;
-using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
-using Volo.Abp.ObjectMapping;
namespace Yi.Framework.TenantManagement.Domain
{
@@ -96,21 +94,23 @@ namespace Yi.Framework.TenantManagement.Domain
private ConnectionStrings? MaptoString(string tenantConnectionString)
{
- tenantConnectionString = tenantConnectionString.TrimEnd(';');
- var strSpiteds = tenantConnectionString.Split(";");
- if (strSpiteds.Count() == 0)
- {
- return null;
+ //tenantConnectionString = tenantConnectionString.TrimEnd(';');
+ //var strSpiteds = tenantConnectionString.Split(";");
+ //if (strSpiteds.Count() == 0)
+ //{
+ // return null;
- }
+ //}
var connectionStrings = new ConnectionStrings();
- foreach (string strSpited in strSpiteds)
- {
- var key = strSpited.Split('=')[0];
- var value = strSpited.Split('=')[1];
- connectionStrings[key] = value;
- }
+ //foreach (string strSpited in strSpiteds)
+ //{
+ // var key = strSpited.Split('=')[0];
+ // var value = strSpited.Split('=')[1];
+ // connectionStrings[key] = value;
+ //}
+ connectionStrings["test"] = tenantConnectionString;
+
return connectionStrings;
}
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantAggregateRoot.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantAggregateRoot.cs
index e261b155..7dbf4739 100644
--- a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantAggregateRoot.cs
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantAggregateRoot.cs
@@ -5,10 +5,12 @@ using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.TenantManagement;
+using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.TenantManagement.Domain
{
[SugarTable("Tenant")]
+ [MasterTenant]
public class TenantAggregateRoot : FullAuditedAggregateRoot, IHasEntityVersion
{
public TenantAggregateRoot()
@@ -21,8 +23,8 @@ namespace Yi.Framework.TenantManagement.Domain
SetName(name);
}
- [SugarColumn(IsPrimaryKey =true)]
- public override Guid Id { get ; protected set; }
+ [SugarColumn(IsPrimaryKey = true)]
+ public override Guid Id { get; protected set; }
public virtual string Name { get; protected set; }
public int EntityVersion { get; protected set; }
@@ -30,9 +32,9 @@ namespace Yi.Framework.TenantManagement.Domain
public DbType DbType { get; protected set; }
- [SugarColumn(IsIgnore=true)]
+ [SugarColumn(IsIgnore = true)]
public override ExtraPropertyDictionary ExtraProperties { get => base.ExtraProperties; protected set => base.ExtraProperties = value; }
- public virtual void SetConnectionString(DbType dbType,string connectionString)
+ public virtual void SetConnectionString(DbType dbType, string connectionString)
{
DbType = dbType;
TenantConnectionString = connectionString;
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantManagementExtensions.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantManagementExtensions.cs
new file mode 100644
index 00000000..ec37f404
--- /dev/null
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/TenantManagementExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.MultiTenancy;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace Yi.Framework.TenantManagement.Domain
+{
+ public static class TenantManagementExtensions
+ {
+ public static IDisposable ChangeMaster(this ICurrentTenant currentTenant)
+ {
+ return currentTenant.Change(null, DbConnOptions.MasterTenantDbDefaultName);
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/Yi.Framework.TenantManagement.Domain.csproj b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/Yi.Framework.TenantManagement.Domain.csproj
index 934dbab0..4b246a2c 100644
--- a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/Yi.Framework.TenantManagement.Domain.csproj
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/Yi.Framework.TenantManagement.Domain.csproj
@@ -8,7 +8,8 @@
-
+
+
diff --git a/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/TenantConst.cs b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/TenantConst.cs
new file mode 100644
index 00000000..dfd192b7
--- /dev/null
+++ b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/TenantConst.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.TenantManagement.Domain.Shared
+{
+ public class TenantConst
+ {
+ public static string TenantDbDefaultName = "Master";
+ }
+}
diff --git a/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/Yi.Framework.TenantManagement.Domain.Shared.csproj b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/Yi.Framework.TenantManagement.Domain.Shared.csproj
new file mode 100644
index 00000000..5ce88f6d
--- /dev/null
+++ b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/Yi.Framework.TenantManagement.Domain.Shared.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/YiFrameworkTenantManagementDomainSharedModule.cs b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/YiFrameworkTenantManagementDomainSharedModule.cs
new file mode 100644
index 00000000..d0784856
--- /dev/null
+++ b/Yi.Abp.Net8/module/tenant-management/YiFrameworkTenantManagementDomain.Shared/YiFrameworkTenantManagementDomainSharedModule.cs
@@ -0,0 +1,11 @@
+using Volo.Abp.Modularity;
+using Volo.Abp.TenantManagement;
+
+namespace YiFrameworkTenantManagementDomain.Shared
+{
+ [DependsOn(typeof(AbpTenantManagementDomainSharedModule))]
+ public class YiFrameworkTenantManagementDomainSharedModule : AbpModule
+ {
+
+ }
+}
diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/MultiTenantConnectionStringResolver2.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/MultiTenantConnectionStringResolver2.cs
deleted file mode 100644
index 263aa0de..00000000
--- a/Yi.Abp.Net8/src/Yi.Abp.Web/MultiTenantConnectionStringResolver2.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
-using Volo.Abp.Data;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.MultiTenancy;
-
-[Dependency(ReplaceServices = true)]
-public class MultiTenantConnectionStringResolver2 : DefaultConnectionStringResolver
-{
- private readonly ICurrentTenant _currentTenant;
- private readonly IServiceProvider _serviceProvider;
-
- public MultiTenantConnectionStringResolver2(
- IOptionsMonitor options,
- ICurrentTenant currentTenant,
- IServiceProvider serviceProvider)
- : base(options)
- {
- _currentTenant = currentTenant;
- _serviceProvider = serviceProvider;
- }
-
- public override async Task ResolveAsync(string? connectionStringName = null)
- {
- if (_currentTenant.Id == null)
- {
- //No current tenant, fallback to default logic
- return await base.ResolveAsync(connectionStringName);
- }
-
- var tenant = await FindTenantConfigurationAsync(_currentTenant.Id.Value);
-
- if (tenant == null || tenant.ConnectionStrings.IsNullOrEmpty())
- {
- //Tenant has not defined any connection string, fallback to default logic
- return await base.ResolveAsync(connectionStringName);
- }
-
- var tenantDefaultConnectionString = tenant.ConnectionStrings?.Default;
-
- //Requesting default connection string...
- if (connectionStringName == null ||
- connectionStringName == ConnectionStrings.DefaultConnectionStringName)
- {
- //Return tenant's default or global default
- return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
- ? tenantDefaultConnectionString!
- : Options.ConnectionStrings.Default!;
- }
-
- //Requesting specific connection string...
- var connString = tenant.ConnectionStrings?.GetOrDefault(connectionStringName);
- if (!connString.IsNullOrWhiteSpace())
- {
- //Found for the tenant
- return connString!;
- }
-
- //Fallback to the mapped database for the specific connection string
- var database = Options.Databases.GetMappedDatabaseOrNull(connectionStringName);
- if (database != null && database.IsUsedByTenants)
- {
- connString = tenant.ConnectionStrings?.GetOrDefault(database.DatabaseName);
- if (!connString.IsNullOrWhiteSpace())
- {
- //Found for the tenant
- return connString!;
- }
- }
-
- //Fallback to tenant's default connection string if available
- if (!tenantDefaultConnectionString.IsNullOrWhiteSpace())
- {
- return tenantDefaultConnectionString!;
- }
-
- return await base.ResolveAsync(connectionStringName);
- }
-
- [Obsolete("Use ResolveAsync method.")]
- public override string Resolve(string? connectionStringName = null)
- {
- if (_currentTenant.Id == null)
- {
- //No current tenant, fallback to default logic
- return base.Resolve(connectionStringName);
- }
-
- var tenant = FindTenantConfiguration(_currentTenant.Id.Value);
-
- if (tenant == null || tenant.ConnectionStrings.IsNullOrEmpty())
- {
- //Tenant has not defined any connection string, fallback to default logic
- return base.Resolve(connectionStringName);
- }
-
- var tenantDefaultConnectionString = tenant.ConnectionStrings?.Default;
-
- //Requesting default connection string...
- if (connectionStringName == null ||
- connectionStringName == ConnectionStrings.DefaultConnectionStringName)
- {
- //Return tenant's default or global default
- return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
- ? tenantDefaultConnectionString!
- : Options.ConnectionStrings.Default!;
- }
-
- //Requesting specific connection string...
- var connString = tenant.ConnectionStrings?.GetOrDefault(connectionStringName);
- if (!connString.IsNullOrWhiteSpace())
- {
- //Found for the tenant
- return connString!;
- }
-
- //Fallback to tenant's default connection string if available
- if (!tenantDefaultConnectionString.IsNullOrWhiteSpace())
- {
- return tenantDefaultConnectionString!;
- }
-
- //Try to find the specific connection string for given name
- var connStringInOptions = Options.ConnectionStrings.GetOrDefault(connectionStringName);
- if (!connStringInOptions.IsNullOrWhiteSpace())
- {
- return connStringInOptions!;
- }
-
- //Fallback to the global default connection string
- var defaultConnectionString = Options.ConnectionStrings.Default;
- if (!defaultConnectionString.IsNullOrWhiteSpace())
- {
- return defaultConnectionString!;
- }
-
- throw new AbpException("No connection string defined!");
- }
-
- protected virtual async Task FindTenantConfigurationAsync(Guid tenantId)
- {
- using (var serviceScope = _serviceProvider.CreateScope())
- {
- var tenantStore = serviceScope
- .ServiceProvider
- .GetRequiredService();
-
- return await tenantStore.FindAsync(tenantId);
- }
- }
-
- [Obsolete("Use FindTenantConfigurationAsync method.")]
- protected virtual TenantConfiguration? FindTenantConfiguration(Guid tenantId)
- {
- using (var serviceScope = _serviceProvider.CreateScope())
- {
- var tenantStore = serviceScope
- .ServiceProvider
- .GetRequiredService();
-
- return tenantStore.Find(tenantId);
- }
- }
-}
diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Program.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/Program.cs
index 14da5fa8..48832fce 100644
--- a/Yi.Abp.Net8/src/Yi.Abp.Web/Program.cs
+++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Program.cs
@@ -1,8 +1,5 @@
-using Microsoft.Extensions.DependencyInjection.Extensions;
using Serilog;
using Serilog.Events;
-using Volo.Abp.Data;
-using Volo.Abp.MultiTenancy;
using Yi.Abp.Web;
//创建日志,可使用{SourceContext}记录
@@ -26,7 +23,6 @@ try
builder.Host.UseAutofac();
builder.Host.UseSerilog();
await builder.Services.AddApplicationAsync();
- builder.Services.Replace(new ServiceDescriptor(typeof(IConnectionStringResolver), typeof(MultiTenantConnectionStringResolver2), ServiceLifetime.Transient));
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
index f4427b69..d42c1422 100644
--- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
+++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
@@ -1,5 +1,4 @@
using System.Text;
-using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors;
using Microsoft.IdentityModel.Tokens;
@@ -14,6 +13,7 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
+using Volo.Abp.MultiTenancy;
using Volo.Abp.Swashbuckle;
using Yi.Abp.Application;
using Yi.Abp.SqlsugarCore;
@@ -107,6 +107,12 @@ namespace Yi.Abp.Web
});
});
+ //配置多租户
+ Configure(options =>
+ {
+ //基于cookie jwt不好用,有坑
+ options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName);
+ });
//jwt鉴权
var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get();