前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >osharp多租户数据建库隔离方案

osharp多租户数据建库隔离方案

原创
作者头像
吴晓阳
修改2025-02-28 16:11:43
修改2025-02-28 16:11:43
250
举报

osharp多租户数据建库隔离方案

加租户配置文件

代码语言:C#
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OSharp.Core
{
    public class Tenant
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Domain { get; set; } // 租户域名
        public string ConnectionString { get; set; } // 租户数据库连接字符串
                                                     // 其他租户相关属性
    }
}

修改ConnectionStringProvider.cs使用选定租户的数据库连接

代码语言:C#
复制
// -----------------------------------------------------------------------
//  <copyright file="ConnectionStringProvider.cs" company="OSharp开源团队">
//      Copyright (c) 2014-2021 OSharp. All rights reserved.
//  </copyright>
//  <site>http://www.osharp.org</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2021-03-20 21:42</last-date>
// -----------------------------------------------------------------------

using Microsoft.Extensions.DependencyInjection;
using OSharp.Core;

namespace OSharp.Entity;

/// <summary>
/// 数据库连接字符串提供者
/// </summary>
public class ConnectionStringProvider : IConnectionStringProvider
{
    private readonly IDictionary<string, OsharpDbContextOptions> _dbContexts;
    private readonly ISlaveDatabaseSelector[] _slaveDatabaseSelectors;
    private readonly IMasterSlaveSplitPolicy _masterSlavePolicy;
    private readonly Tenant _tenant;

    /// <summary>
    /// 初始化一个<see cref="ConnectionStringProvider"/>类型的新实例
    /// </summary>
    public ConnectionStringProvider(IServiceProvider provider)
    {
        _tenant = provider.GetService<Tenant>();
        _dbContexts = provider.GetOSharpOptions().DbContexts;
        _masterSlavePolicy = provider.GetService<IMasterSlaveSplitPolicy>();
        _slaveDatabaseSelectors = provider.GetServices<ISlaveDatabaseSelector>().ToArray();
    }

    /// <summary>
    /// 获取指定数据上下文类型的数据库连接字符串
    /// </summary>
    /// <param name="dbContextType">数据上下文类型</param>
    /// <returns></returns>
    public virtual string GetConnectionString(Type dbContextType)
    {
        return _tenant.ConnectionString;
        /*
        OsharpDbContextOptions dbContextOptions = _dbContexts.Values.FirstOrDefault(m => m.DbContextType == dbContextType);
        if (dbContextOptions == null)
        {
            throw new OsharpException($"数据上下文“{dbContextType}”的数据上下文配置信息不存在");
        }

        bool isSlave = _masterSlavePolicy.IsToSlaveDatabase(dbContextOptions);
        if (!isSlave)
        {
            return dbContextOptions.ConnectionString;
        }
            
        SlaveDatabaseOptions[] slaves = dbContextOptions.Slaves;
        ISlaveDatabaseSelector slaveDatabaseSelector = _slaveDatabaseSelectors.LastOrDefault(m => m.Name == dbContextOptions.SlaveSelectorName)
            ?? _slaveDatabaseSelectors.First(m => m.Name == "Weight");
        SlaveDatabaseOptions slave = slaveDatabaseSelector.Select(slaves);
        return slave.ConnectionString;
        */
    }
}

修改Startup.cs注入租户配置文件

代码语言:C#
复制
// -----------------------------------------------------------------------
//  <copyright file="Startup.cs" company="OSharp开源团队">
//      Copyright (c) 2014-2020 OSharp. All rights reserved.
//  </copyright>
//  <site>http://www.osharp.org</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2020-03-26 21:47</last-date>
// -----------------------------------------------------------------------

using Liuliu.Demo.Authorization;
using Liuliu.Demo.Identity;
using Liuliu.Demo.Infos;
using Liuliu.Demo.Systems;
using Liuliu.Demo.Web.Startups;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using OSharp.AspNetCore;
using OSharp.AspNetCore.Routing;
using OSharp.AutoMapper;
using OSharp.Core;
using OSharp.Log4Net;
//using OSharp.MiniProfiler;
using OSharp.Swagger;


namespace Liuliu.Demo.Web
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor(); // 注册 IHttpContextAccessor

            services.AddScoped<Tenant>(provider =>
            {
                var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
                var httpContext = httpContextAccessor.HttpContext;
                if (httpContext != null)
                {
                    return GetTenantByDomain(httpContext.Request.Host.Value);
                }
                return new Tenant
                {
                    Id = 1,
                    Name = "Default Tenant",
                    Domain = "default",
                    ConnectionString = "Server=(localdb)\\mssqllocaldb;Database=osharpns-dev01;Trusted_Connection=True;MultipleActiveResultSets=true"
                };
            });

            //services.AddDatabaseDeveloperPageExceptionFilter();
            services.AddOSharp()
                .AddPack<Log4NetPack>()
                .AddPack<AutoMapperPack>()
                .AddPack<EndpointsPack>()
                //.AddPack<MiniProfilerPack>()
                .AddPack<SwaggerPack>()
                //.AddPack<RedisPack>()
                .AddPack<AuthenticationPack>()
                .AddPack<FunctionAuthorizationPack>()
                .AddPack<DataAuthorizationPack>()
                .AddPack<SqlServerDefaultDbContextMigrationPack>()
                .AddPack<AuditPack>()
                .AddPack<InfosPack>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(WebApplication app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //app.UseMigrationsEndPoint();
            }
            else
            {
                app.UseExceptionHandler("/#/500");
                app.UseHsts();
                //app.UseHttpsRedirection(); // 启用HTTPS
            }

            //app.UseMiddleware<HostHttpCryptoMiddleware>();
            //app.UseMiddleware<JsonNoFoundHandlerMiddleware>();
            app.UseMiddleware<JsonExceptionHandlerMiddleware>();
            app.UseDefaultFiles();
            app.UseStaticFiles();
            app.UseOSharp();
        }

        private Tenant GetTenantByDomain(string domain)
        {
            // 根据域名获取租户信息的逻辑
            // 这里可以从数据库或配置文件中获取
            return new Tenant
            {
                Id = 1,
                Name = "Default Tenant",
                Domain = domain,
                ConnectionString = "Server=(localdb)\\mssqllocaldb;Database=osharpns-dev02;Trusted_Connection=True;MultipleActiveResultSets=true"
            };
        }
    }
}

修改Program.cs

代码语言:C#
复制
// -----------------------------------------------------------------------
//  <copyright file="Program.cs" company="OSharp开源团队">
//      Copyright (c) 2014-2018 OSharp. All rights reserved.
//  </copyright>
//  <site>http://www.osharp.org</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2018-06-27 4:50</last-date>
// -----------------------------------------------------------------------

using AspectCore.Extensions.Hosting;
using Liuliu.Demo.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;


var builder = WebApplication.CreateBuilder(args);

var startup = new Startup();
startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();

将所有的数据库配置文件中的HasName改成HasDatabaseName

将项目设置为.net8.0

作者

吴晓阳

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • osharp多租户数据建库隔离方案
    • 加租户配置文件
    • 修改ConnectionStringProvider.cs使用选定租户的数据库连接
    • 修改Startup.cs注入租户配置文件
    • 修改Program.cs
    • 将所有的数据库配置文件中的HasName改成HasDatabaseName
    • 将项目设置为.net8.0
  • 作者
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档