Multi-tenant sub-library sub-table in net core perfectly solves the problem of multi-tenant sub-library sub-table in net core

Net core perfectly solves the problem of multi-tenant sub-library and table division

 A few days ago, someone wanted to make a multi-tenant platform. Each tenant has a library that can be horizontally expanded. The application terminal switches to a different tenant library according to the login information.

It is planned to be implemented with ef core, they say that they cannot do it, they need to dynamically create dbContext, which is not easy to achieve

However, this can be easily solved using CRL

 

The following is a demo database, there are two libraries testdb and testdb2, the query results are as follows

aims:

According to the incoming login information, the different libraries are connected, and the query returns the result.

In fact, this requirement is the realization of sub-database and sub-table.By setting the database / table mapping relationship, matching based on the incoming positioning data, finding the correct database table configuration, and generating data access objects

 

Take the core console program as an example

Copy code
class Program
    {
        static IServiceProvider provider;
        static Program()
        {
            var services = new ServiceCollection();
            services.AddCRL<DBLocationCreator>();
            services.AddScoped<Code.Sharding.MemberManage>();

            provider = services.BuildServiceProvider();
            provider.UseCRL();
        }

        static void Main(string[] args)
        {

        label1:
            var instance = provider.GetService<Code.Sharding.MemberManage>();
            var data = new Code.Sharding.MemberSharding();

            data.Code = "01";
            instance.SetLocation (data);
            var find1 = instance.QueryItem (b => b.Id> 0) ?. Name; 
            Console.WriteLine ($ "location data input {data.Code}, query value {find1}"); 

            data.Code = "02 "; 
            instance.SetLocation (data); 
            var find2 = instance.QueryItem (b => b.Id> 0) ?. Name; 
            Console.WriteLine ($" location data input {data.Code}, query value is {find2} "); 
            Console.ReadLine (); 
            goto label1; 
        } 
    }
Copy code

In the above code, the location data Code is passed in through the SetLocation method, and the data is queried and printed out through the QueryItem method

 

Inject the location configuration through services.AddCRL <DBLocationCreator> (), DBLocationCreator inherits the interface IDBLocationCreator

This is in full compliance with the core injection specification, and the positioning settings can be dynamically read through configuration or database storage

Copy code
 public class DBLocationCreator : IDBLocationCreator
    {
        ISettingConfigBuilder _settingConfigBuilder;
        public DBLocationCreator(ISettingConfigBuilder settingConfigBuilder)
        {
            _settingConfigBuilder = settingConfigBuilder;
        }

        public void Init()
        {
            //自定义定位
            _settingConfigBuilder.RegisterLocation<Code.Sharding.MemberSharding>((t, a) =>
            {
                var tableName = t.TableName;
                var dbName = a.Code == "02" ? "testdb2" : "testdb";
                var dataBase = $"Data Source=.;Initial Catalog={dbName};User ID=sa;Password=123";
                //返回定位库和表名
                return new CRL.Sharding.Location(dataBase, tableName);
            });
            _settingConfigBuilder.RegisterDBAccessBuild(dbLocation =>
            {
                var connectionString = "Data Source=.;Initial Catalog=testdb;User ID=sa;Password=123";
                if (dbLocation.ShardingLocation != null)
                {
                    connectionString = dbLocation.ShardingLocation.DataBaseSource;
                }
                return new CRL.DBAccessBuild(DBType.MSSQL, connectionString);
            });
        }
    }
Copy code

In the Init method, two operations are implemented. RegisterLocation defines how to return different libraries / tables based on the positioning data Code.

Data access through RegisterDBAccessBuild

 Object definition

Copy code
    public class MemberSharding : CRL.IModel
    {
        [CRL.Attribute.Field(KeepIdentity=true)]//保持插入主键
        public int Id
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public string Code;
    }
    public class MemberManage : CRL.Sharding.BaseProvider<MemberSharding>
    {

    }
Copy code

 

Run the test program and the result output is

 

The above code uses custom positioning parameters and positioning rules, without any coupling, and the call is also very simple, perfectly achieving the expected effect

Test code address: https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest

 A few days ago, someone wanted to make a multi-tenant platform. Each tenant has a library that can be horizontally expanded. The application terminal switches to a different tenant library according to the login information.

It is planned to be implemented with ef core, they say that they cannot do it, they need to dynamically create dbContext, which is not easy to achieve

However, this can be easily solved using CRL

 

The following is a demo database, there are two libraries testdb and testdb2, the query results are as follows

aims:

According to the incoming login information, the different libraries are connected, and the query returns the result.

In fact, this requirement is the realization of sub-database and sub-table.By setting the database / table mapping relationship, matching based on the incoming positioning data, finding the correct database table configuration, and generating data access objects

 

Take the core console program as an example

Copy code
class Program
    {
        static IServiceProvider provider;
        static Program()
        {
            var services = new ServiceCollection();
            services.AddCRL<DBLocationCreator>();
            services.AddScoped<Code.Sharding.MemberManage>();

            provider = services.BuildServiceProvider();
            provider.UseCRL();
        }

        static void Main(string[] args)
        {

        label1:
            var instance = provider.GetService<Code.Sharding.MemberManage>();
            var data = new Code.Sharding.MemberSharding();

            data.Code = "01";
            instance.SetLocation (data);
            var find1 = instance.QueryItem (b => b.Id> 0) ?. Name; 
            Console.WriteLine ($ "location data input {data.Code}, query value {find1}"); 

            data.Code = "02 "; 
            instance.SetLocation (data); 
            var find2 = instance.QueryItem (b => b.Id> 0) ?. Name; 
            Console.WriteLine ($" location data input {data.Code}, query value is {find2} "); 
            Console.ReadLine (); 
            goto label1; 
        } 
    }
Copy code

In the above code, the location data Code is passed in through the SetLocation method, and the data is queried and printed out through the QueryItem method

 

Inject the location configuration through services.AddCRL <DBLocationCreator> (), DBLocationCreator inherits the interface IDBLocationCreator

This is in full compliance with the core injection specification, and the positioning settings can be dynamically read through configuration or database storage

Copy code
 public class DBLocationCreator : IDBLocationCreator
    {
        ISettingConfigBuilder _settingConfigBuilder;
        public DBLocationCreator(ISettingConfigBuilder settingConfigBuilder)
        {
            _settingConfigBuilder = settingConfigBuilder;
        }

        public void Init()
        {
            //自定义定位
            _settingConfigBuilder.RegisterLocation<Code.Sharding.MemberSharding>((t, a) =>
            {
                var tableName = t.TableName;
                var dbName = a.Code == "02" ? "testdb2" : "testdb";
                var dataBase = $"Data Source=.;Initial Catalog={dbName};User ID=sa;Password=123";
                //返回定位库和表名
                return new CRL.Sharding.Location(dataBase, tableName);
            });
            _settingConfigBuilder.RegisterDBAccessBuild(dbLocation =>
            {
                var connectionString = "Data Source=.;Initial Catalog=testdb;User ID=sa;Password=123";
                if (dbLocation.ShardingLocation != null)
                {
                    connectionString = dbLocation.ShardingLocation.DataBaseSource;
                }
                return new CRL.DBAccessBuild(DBType.MSSQL, connectionString);
            });
        }
    }
Copy code

In the Init method, two operations are implemented. RegisterLocation defines how to return different libraries / tables based on the positioning data Code.

Data access through RegisterDBAccessBuild

 Object definition

Copy code
    public class MemberSharding : CRL.IModel
    {
        [CRL.Attribute.Field(KeepIdentity=true)]//保持插入主键
        public int Id
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public string Code;
    }
    public class MemberManage : CRL.Sharding.BaseProvider<MemberSharding>
    {

    }
Copy code

 

Run the test program and the result output is

 

The above code uses custom positioning parameters and positioning rules, without any coupling, and the call is also very simple, perfectly achieving the expected effect

Test code address: https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest

Guess you like

Origin www.cnblogs.com/Leo_wl/p/12733089.html