Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlSugar 多个 dbcontext 要怎么注册 实现 #32

Closed
binyly opened this issue Nov 25, 2019 · 4 comments
Closed

SqlSugar 多个 dbcontext 要怎么注册 实现 #32

binyly opened this issue Nov 25, 2019 · 4 comments
Labels
好问题 Good for newcomers 新需求 New feature or request 需要高手帮忙 Extra attention is needed

Comments

@binyly
Copy link
Contributor

binyly commented Nov 25, 2019

在日常的使用当中,有需求要连接多个数据库来操作。这时候要怎么去处理这个dbcontext呢?

后期有安排这方面的东西吗?

@anjoy8 anjoy8 added 好问题 Good for newcomers 新需求 New feature or request 需要高手帮忙 Extra attention is needed labels Nov 25, 2019
@shanvenleo
Copy link

根据 SqlSugar 官方文档简单修改

  1. 添加 BaseDbContext 基类

  2. 添加 DbSet 数据集类

  3. 添加 SugarDbOptions 配置类

  4. 根据项目需要,添加 DbContext01,DbContext02,...,继承于 BaseDbContext

  5. 添加扩展方法 ServiceCollectionExtensions.AddSugarDbContext

  6. 在 ConfigureServices 添加 DbContext 服务注入 ConfigureServices

    具体代码如下

    // 1. 添加 BaseDbContext 基类
	namespace DbContext
{
    public class BaseDbContext
    {
        private readonly ILogger<BaseDbContext> _logger;

        public BaseDbContext(IOptionsSnapshot<SugarDbOptions> namedOptionsAccessor,
            ILoggerFactory loggerFactory
            )
        {
            _logger = loggerFactory.CreateLogger<BaseDbContext>();
            var options = namedOptionsAccessor.Get(this.GetType().Name);
            string connectionString = options.ConnectionString;
            string dbType = options.DbType;
            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = connectionString,
                DbType = (DbType)Enum.Parse(typeof(DbType), dbType),//DbType.SqlServer,
                InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
                IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了

            });
            //调式代码 用来打印SQL 
            Db.Aop.OnLogExecuting = (sql, pars) =>
            {
                _logger.LogInformation(sql + "\r\n" +
                    Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));

            };
        }

        public BaseDbContext(string connectionString, string dbType)
        {
            this.GetType();
            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = connectionString,
                DbType = (DbType)Enum.Parse(typeof(DbType), dbType),//DbType.SqlServer,
                InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
                IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了

            });
            //调式代码 用来打印SQL 
            Db.Aop.OnLogExecuting = (sql, pars) =>
            {
                _logger.LogInformation(sql + "\r\n" +
                    Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
            };

        }
        //注意:不能写成静态的
        public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
    }
}
// 2. 添加 DbSet 数据集类
namespace DbContext
{
    //可以直接用SimpleClient也可以扩展一个自个的类 
    //推荐直接用 SimpleClient 
    //为了照顾需要扩展的朋友,我们就来扩展一个SimpleClient,取名叫DbSet
    public class DbSet<T> : SimpleClient<T> where T : class, new()
    {
        public DbSet(SqlSugarClient context) : base(context)
        {

        }
        //SimpleClient中的方法满足不了你,你可以扩展自已的方法
        public List<T> GetByIds(dynamic[] ids)
        {
            return Context.Queryable<T>().In(ids).ToList(); ;
        }
    }
}
// 3. 添加 SugarDbOptions 配置类
namespace DbContext
{
    public class SugarDbOptions
    {
        public string ConnectionString { get; set; } //连接字符串
        public string DbType { get; set; } //数据库类型
    }
}
// 4. 根据项目需要,添加 DbContext01,DbContext02,...,继承于 BaseDbContext 
namespace DbContext
{
    public class DbContext01 : BaseDbContext
    {
        public DbContext01(IOptionsSnapshot<SugarDbOptions> namedOptionsAccessor,ILoggerFactory loggerFactory):base(namedOptionsAccessor, loggerFactory){}
        // DbSet数据表
        public DbSet<1>1 { get { return new DbSet<1>(Db); } }
        public DbSet<2>2 { get { return new DbSet<2>(Db); } }
        public DbSet<3>3 { get { return new DbSet<3>(Db); } }
    }
}
// 5. 添加扩展方法 ServiceCollectionExtensions.AddSugarDbContext
namespace Extensions
{
        public static IServiceCollection AddSugarDbContext<T>(this IServiceCollection services, Action<SugarDbOptions> setupAction) where T : class
        {
            services.AddScoped<T>();
            string name = typeof(T).Name;
            var options = services.AddOptions<SugarDbOptions>(name);
            services.Configure<SugarDbOptions>(name, setupAction);
            return services;
        }
    }
}
// 6. 在 ConfigureServices 添加 DbContext 服务注入 ConfigureServices
            services.AddSugarDbContext<DbContext01>(options =>
            {
                options.ConnectionString = Configuration["DbContext:DbContext01:ConnectionString"];
                options.DbType = Configuration["DbContext:DbContext01:DbType"];
            });
//对应配置文件
  "DbContext": {
    "DbContext01": {
      "Enabled": true,
      "ConnectionString": "Server=.;Database=Db01;User ID=sa;Password=123;",
      "DbType": "SqlServer"
    }
}
  1. 后续问题
    这个方法能解决按不同业务模块分库的问题.对于水平分库扩展还有改进的空间.
    比如项目初期10万用户以内只有一个库,每增加10万用户自动增加一个库.
    或者多租户系统,每个增加租户添加一个库.
    需要根据不同的库动态切换连接字符串.
    暂时还没有想到解决方案....

@anjoy8
Copy link
Owner

anjoy8 commented Dec 12, 2019

你这个是配置多个上下文,每个上下文对应一个db库,如果使用的话,再去切换吧。

他问是好像是同时操作两个db,就是你说的,A租户过来自动使用A数据库连接字符串,B操作B。

@binyly
Copy link
Contributor Author

binyly commented Dec 13, 2019

services.AddScoped(provider =>
{
Func<string, SqlSugarClient> func = key =>
{
switch (key)
{
case "1":
return new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = sqlSugarConfig.Item2,
DbType = sqlSugarConfig.Item1,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
});
case "2":
return new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = sqlSugarConfig.Item2,
DbType = sqlSugarConfig.Item1,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
});

                    default:
                        throw new NotSupportedException($"Not Support key : {key}");
                }
            };
            return func;
        });

private readonly Func<string, SqlSugarClient> _serviceAccessor;
public HomeController( Func<string, SqlSugarClient> serviceAccessor
)
{
_serviceAccessor=serviceAccessor;
}
获取方式 var db =_serviceAccessor("1")

这是另外一个大佬提供的方案,可以学习一下

@anjoy8
Copy link
Owner

anjoy8 commented Dec 23, 2019

我这边实现了多库操作,但是不是多个上下文的。
#46

@anjoy8 anjoy8 closed this as completed Dec 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
好问题 Good for newcomers 新需求 New feature or request 需要高手帮忙 Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants