diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
index 8ad3c5d4..0d2e1345 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs
@@ -51,66 +51,5 @@ namespace Yi.Framework.SqlSugarCore.Abstractions
///
public bool EnabledSaasMultiTenancy { get; set; } = false;
-
- ///
- /// 默认租户库连接,如果不填,那就是默认库的地址
- ///
- public string? MasterSaasMultiTenancyUrl { get; set; }
-
-
- ///
- /// Saas租户连接
- ///
- public List? SaasMultiTenancy { get; set; }
-
- public static string MasterTenantName = "Master";
- public static string DefaultTenantName = "Default";
-
- ///
- /// 获取默认数据库
- ///
- ///
- public SaasMultiTenancyOptions GetDefaultSaasMultiTenancy()
- {
- return new SaasMultiTenancyOptions { Name = DefaultTenantName, Url = Url };
- }
-
- ///
- /// 获取主数据库
- ///
- ///
- public SaasMultiTenancyOptions? GetMasterSaasMultiTenancy()
- {
- if (EnabledSaasMultiTenancy == false)
- {
- return null;
- }
- if (string.IsNullOrEmpty(MasterSaasMultiTenancyUrl))
- {
-
- return new SaasMultiTenancyOptions { Name = MasterTenantName, Url = Url };
- }
- else
- {
- return new SaasMultiTenancyOptions()
- {
- Name = MasterTenantName,
- 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/MasterTenantAttribute.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DefaultTenantTableAttribute.cs
similarity index 80%
rename from Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs
rename to Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DefaultTenantTableAttribute.cs
index fee1dee7..2b2519ef 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/MasterTenantAttribute.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore.Abstractions/DefaultTenantTableAttribute.cs
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Yi.Framework.SqlSugarCore.Abstractions
{
[AttributeUsage(AttributeTargets.Class)]
- public class MasterTenantAttribute : Attribute
+ public class DefaultTenantTableAttribute : Attribute
{
}
}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
index e99d7da2..ef40f34e 100644
--- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
+++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs
@@ -25,7 +25,6 @@ namespace Yi.Framework.SqlSugarCore
///
public ISqlSugarClient SqlSugarClient { get; private set; }
public ICurrentUser CurrentUser => LazyServiceProvider.GetRequiredService();
- private readonly string MasterTenantDbDefaultName = DbConnOptions.MasterTenantName;
private IAbpLazyServiceProvider LazyServiceProvider { get; }
private IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetRequiredService();
@@ -38,6 +37,7 @@ namespace Yi.Framework.SqlSugarCore
public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance);
public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService>().Value;
+ public AbpDbConnectionOptions ConnectionOptions=> LazyServiceProvider.LazyGetRequiredService>().Value;
private ISqlSugarDbConnectionCreator _dbConnectionCreator;
public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient)
@@ -69,21 +69,23 @@ namespace Yi.Framework.SqlSugarCore
///
protected virtual string GetCurrentConnectionString()
{
+ var defautlUrl = Options.Url ?? ConnectionOptions.GetConnectionStringOrNull(ConnectionStrings.DefaultConnectionStringName);
+ //如果未开启多租户,返回db url 或者 默认连接字符串
+ if (!Options.EnabledSaasMultiTenancy)
+ {
+ return defautlUrl;
+ }
+
+ //开启了多租户
var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService();
var connectionString = connectionStringResolver.ResolveAsync().Result;
+
//没有检测到使用多租户功能,默认使用默认库即可
if (string.IsNullOrWhiteSpace(connectionString))
{
Volo.Abp.Check.NotNull(Options.Url, "租户默认库Defalut未找到");
- connectionString = Options.Url;
- }
- //如果当前租户是主库,单独使用主要库
- if (CurrentTenant.Name == MasterTenantDbDefaultName)
- {
- var conStrOrNull = Options.GetMasterSaasMultiTenancy();
- Volo.Abp.Check.NotNull(conStrOrNull, "租户主库Master未找到");
- connectionString = conStrOrNull.Url;
+ connectionString = defautlUrl;
}
return connectionString!;
}
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Application/TenantService.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Application/TenantService.cs
index c5477371..11979e9f 100644
--- a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Application/TenantService.cs
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Application/TenantService.cs
@@ -6,6 +6,7 @@ using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.Modularity;
+using Volo.Abp.Uow;
using Yi.Framework.Ddd.Application;
using Yi.Framework.SqlSugarCore.Abstractions;
using Yi.Framework.TenantManagement.Application.Contracts;
@@ -113,6 +114,7 @@ namespace Yi.Framework.TenantManagement.Application
[HttpPut("tenant/init/{id}")]
public async Task InitAsync([FromRoute] Guid id)
{
+ await CurrentUnitOfWork.SaveChangesAsync();
using (CurrentTenant.Change(id))
{
await CodeFirst(this.LazyServiceProvider);
@@ -124,10 +126,20 @@ namespace Yi.Framework.TenantManagement.Application
private async Task CodeFirst(IServiceProvider service)
{
var moduleContainer = service.GetRequiredService();
- var db = await _repository.GetDbContextAsync();
- //尝试创建数据库
- db.DbMaintenance.CreateDatabase();
+ //没有数据库,不能创工作单元,创建库,先关闭
+ ISqlSugarClient db = null;
+ using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
+ {
+ db = await _repository.GetDbContextAsync();
+ //尝试创建数据库
+ db.DbMaintenance.CreateDatabase();
+ await uow.CompleteAsync();
+ }
+
+
+
+
List types = new List();
foreach (var module in moduleContainer.Modules)
@@ -135,6 +147,7 @@ namespace Yi.Framework.TenantManagement.Application
types.AddRange(module.Assembly.GetTypes()
.Where(x => x.GetCustomAttribute() == null)
.Where(x => x.GetCustomAttribute() != null)
+ .Where(x=>x.GetCustomAttribute() is 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 684be613..34750ce5 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
@@ -93,24 +93,8 @@ namespace Yi.Framework.TenantManagement.Domain
private ConnectionStrings? MaptoString(string tenantConnectionString)
{
-
- //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;
- //}
- connectionStrings["test"] = tenantConnectionString;
-
+ connectionStrings[ConnectionStrings.DefaultConnectionStringName] = 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 55bfbc00..7f0424c3 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
@@ -10,7 +10,7 @@ using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.TenantManagement.Domain
{
[SugarTable("YiTenant")]
- [MasterTenant]
+ [DefaultTenantTable]
public class TenantAggregateRoot : FullAuditedAggregateRoot, IHasEntityVersion
{
public TenantAggregateRoot()
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
index dbe47fa1..9b2ee8ae 100644
--- 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
@@ -1,18 +1,14 @@
-using Volo.Abp.MultiTenancy;
+using Volo.Abp.Data;
+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.MasterTenantName);
- }
-
public static IDisposable ChangeDefalut(this ICurrentTenant currentTenant)
{
- return currentTenant.Change(null, DbConnOptions.DefaultTenantName);
+ return currentTenant.Change(null, ConnectionStrings.DefaultConnectionStringName);
}
}
}
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiMultiTenantConnectionStringResolver.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiMultiTenantConnectionStringResolver.cs
index 503c3966..6da0fd34 100644
--- a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiMultiTenantConnectionStringResolver.cs
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiMultiTenantConnectionStringResolver.cs
@@ -44,14 +44,16 @@ public class YiMultiTenantConnectionStringResolver : DefaultConnectionStringReso
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!;
- //}
+ 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?.FirstOrDefault().Value;
diff --git a/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiTenantConfigurationProvider.cs b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiTenantConfigurationProvider.cs
new file mode 100644
index 00000000..0914e47c
--- /dev/null
+++ b/Yi.Abp.Net8/module/tenant-management/Yi.Framework.TenantManagement.Domain/YiTenantConfigurationProvider.cs
@@ -0,0 +1,74 @@
+using Microsoft.Extensions.Localization;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy.Localization;
+
+namespace Volo.Abp.MultiTenancy;
+
+[Dependency(ReplaceServices =true)]
+public class YiTenantConfigurationProvider : ITenantConfigurationProvider, ITransientDependency
+{
+ protected virtual ITenantResolver TenantResolver { get; }
+ protected virtual ITenantStore TenantStore { get; }
+ protected virtual ITenantResolveResultAccessor TenantResolveResultAccessor { get; }
+ protected virtual IStringLocalizer StringLocalizer { get; }
+
+ public YiTenantConfigurationProvider(
+ ITenantResolver tenantResolver,
+ ITenantStore tenantStore,
+ ITenantResolveResultAccessor tenantResolveResultAccessor,
+ IStringLocalizer stringLocalizer)
+ {
+ TenantResolver = tenantResolver;
+ TenantStore = tenantStore;
+ TenantResolveResultAccessor = tenantResolveResultAccessor;
+ StringLocalizer = stringLocalizer;
+ }
+
+ public virtual async Task GetAsync(bool saveResolveResult = false)
+ {
+ var resolveResult = await TenantResolver.ResolveTenantIdOrNameAsync();
+
+ if (saveResolveResult)
+ {
+ TenantResolveResultAccessor.Result = resolveResult;
+ }
+
+ TenantConfiguration? tenant = null;
+ if (resolveResult.TenantIdOrName != null)
+ {
+ tenant = await FindTenantAsync(resolveResult.TenantIdOrName);
+
+ if (tenant == null)
+ {
+ throw new BusinessException(
+ code: "Volo.AbpIo.MultiTenancy:010001",
+ message: StringLocalizer["TenantNotFoundMessage"],
+ details: StringLocalizer["TenantNotFoundDetails", resolveResult.TenantIdOrName]
+ );
+ }
+
+ if (!tenant.IsActive)
+ {
+ throw new BusinessException(
+ code: "Volo.AbpIo.MultiTenancy:010002",
+ message: StringLocalizer["TenantNotActiveMessage"],
+ details: StringLocalizer["TenantNotActiveDetails", resolveResult.TenantIdOrName]
+ );
+ }
+ }
+
+ return tenant;
+ }
+
+ protected virtual async Task FindTenantAsync(string tenantIdOrName)
+ {
+ if (Guid.TryParse(tenantIdOrName, out var parsedTenantId))
+ {
+ return await TenantStore.FindAsync(parsedTenantId);
+ }
+ else
+ {
+ return await TenantStore.FindAsync(tenantIdOrName);
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/TestOptions.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/TestOptions.cs
new file mode 100644
index 00000000..bbcce5d0
--- /dev/null
+++ b/Yi.Abp.Net8/src/Yi.Abp.Web/TestOptions.cs
@@ -0,0 +1,30 @@
+using Volo.Abp.Data;
+
+namespace Yi.Abp.Web
+{
+ public class TestOptions
+ {
+ public ConnectionStrings2 ConnectionStrings { get; set; }=new ConnectionStrings2();
+
+ public AbpDatabaseInfoDictionary2 Databases { get; set; }=new AbpDatabaseInfoDictionary2();
+ }
+
+ public class ConnectionStrings2 : Dictionary
+ {
+ }
+ public class AbpDatabaseInfoDictionary2 : Dictionary
+ {
+ }
+
+ public class AbpDatabaseInfo2
+ {
+ internal AbpDatabaseInfo2(string databaseName)
+ {
+ DatabaseName = databaseName;
+ MappedConnections = new HashSet();
+ }
+ public string DatabaseName { get; }
+ public HashSet MappedConnections { get; }
+ public bool IsUsedByTenants { get; set; } = true;
+ }
+}
diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
index 3d02c2ea..e6f33dec 100644
--- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
+++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
@@ -15,6 +15,7 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Caching;
+using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Swashbuckle;
using Yi.Abp.Application;
@@ -249,6 +250,8 @@ namespace Yi.Abp.Web
//授权
context.Services.AddAuthorization();
+
+ Configure(configuration);
return Task.CompletedTask;
}
@@ -257,6 +260,10 @@ namespace Yi.Abp.Web
{
var service = context.ServiceProvider;
+ var sss=service.GetRequiredService>().Value;
+
+
+
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();