diff --git a/README.md b/README.md index 615af41..242e172 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ - [按时间自动分表](#按时间自动分表) - [性能测试](#性能测试) - [其它简单操作(非Sharing)](#其它简单操作非sharing) -- [常用配置](#常用配置) - - [多主键支持](#多主键支持) - - [索引支持](#索引支持) +- [高级配置](#高级配置) - [注意事项](#注意事项) - [总结](#总结) @@ -37,31 +35,30 @@ ## 配置 ```c# -ShardingConfig.Init(config => +ServiceCollection services = new ServiceCollection(); +//配置初始化 +services.AddEFCoreSharding(config => { - config.AddAbsDb(DatabaseType.SQLite) - .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, "DataSource=db.db") - .AddPhysicDbGroup() - .SetHashModShardingRule(nameof(Base_UnitTest.Id), 3); + //添加数据源 + config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer); + + //对3取模分表 + config.SetHashModSharding(nameof(Base_UnitTest.Id), 3); }); ``` 上述代码中完成了Sharding配置 - -- **AddAbsDb**是指添加抽象数据库,抽象数据库就是将多个分库看成同一个数据库来进行操作 -- **AddPhysicDbGroup**是指添加物理数据库组,在同一组物理数据库中,它们数据库类型相同,拥有的表相同,每个数据库拥有的数据是一致的(之间通过主主复制或主从复制进行数据同步) -- **AddPhysicTable**是指添加物理数据表,传入的Base_UnitTest是抽象数据表(即将Base_UnitTest拆分为Base_UnitTest_0~2) -- **SetHashModShardingRule**是采用哈希取模的分表规则,分表字段为**Id**,取模值为**3**,会自动生成表Base_UnitTest_0,Base_UnitTest_1,Base_UnitTest_2 +- **AddEFCoreSharding**注入EFCoreSharding +- **AddDataSource**添加分表数据源 +- **SetHashModSharding**是采用哈希取模的分表规则,分表字段为**Id**,取模值为**3**,会自动生成表Base_UnitTest_0,Base_UnitTest_1,Base_UnitTest_2 ## 使用 -配置完成,下面开始使用,使用方式**非常简单**,与平常使用基本一致 -首先获取分片仓储接口IShardingDbAccessor +配置完成,下面开始使用,使用方式**非常简单**,与平常使用基本一致 +首先通过注入获取到IShardingDbAccessor ```c# -using(IShardingDbAccessor _db = DbFactory.GetShardingDbAccessor()) -{ - -} +var db=ServiceProvider.GetService(); ``` + 然后即可进行数据操作: ```c# @@ -106,18 +103,16 @@ _db.Update(_newData); //更新多条数据 _db.Update(_insertList); //更新单条数据指定属性 -_db.UpdateAny(_newData, new List { "UserName", "Age" }); +_db.Update(_newData, new List { "UserName", "Age" }); //更新多条数据指定属性 -_db.UpdateAny(_insertList, new List { "UserName", "Age" }); +_db.Update(_insertList, new List { "UserName", "Age" }); //更新指定条件数据 -_db.UpdateWhere(x => x.UserId == "Admin", x => +_db.Update(x => x.UserId == "Admin", x => { x.UserId = "Admin2"; }); //GetList获取表的所有数据 var list=_db.GetList(); -//GetIQPagination获取分页后的数据 -var list=_db.GetIShardingQueryable().GetPagination(pagination); //Max var max=_db.GetIShardingQueryable().Max(x => x.Age); //Min @@ -145,36 +140,44 @@ Assert.AreEqual(succcess, false); using EFCore.Sharding; using EFCore.Sharding.Tests; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using System; -using System.Threading; +using System.Threading.Tasks; -namespace Demo.AutoExpandByDate +namespace Demo.DateSharding { class Program { - static void Main(string[] args) + static async Task Main(string[] args) { DateTime startTime = DateTime.Now.AddMinutes(-5); - DateTime endTime = DateTime.MaxValue; - + ServiceCollection services = new ServiceCollection(); + services.AddLogging(config => + { + config.AddConsole(); + }); //配置初始化 - ShardingConfig.Init(config => + services.AddEFCoreSharding(config => { - config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库 - .AddPhysicDbGroup()//添加物理数据库组 - .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1)//添加物理数据库1 - .SetDateShardingRule(nameof(Base_UnitTest.CreateTime))//设置分表规则 - .AutoExpandByDate(//设置为按时间自动分表 - ExpandByDateMode.PerMinute, - (startTime, endTime, ShardingConfig.DefaultDbGourpName) - ); + //添加数据源 + config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer); + + //按分钟分表 + config.SetDateSharding(nameof(Base_UnitTest.CreateTime), ExpandByDateMode.PerMinute, startTime); }); - var db = DbFactory.GetShardingDbAccessor(); + var serviceProvider = services.BuildServiceProvider(); + + using var scop = serviceProvider.CreateScope(); + + var db = scop.ServiceProvider.GetService(); + var logger = scop.ServiceProvider.GetService>(); + while (true) { try { - db.Insert(new Base_UnitTest + await db.InsertAsync(new Base_UnitTest { Id = Guid.NewGuid().ToString(), Age = 1, @@ -183,17 +186,17 @@ namespace Demo.AutoExpandByDate }); DateTime time = DateTime.Now.AddMinutes(-2); - var count = db.GetIShardingQueryable() + var count = await db.GetIShardingQueryable() .Where(x => x.CreateTime >= time) - .Count(); - Console.WriteLine($"当前数据量:{count}"); + .CountAsync(); + logger.LogWarning("当前数据量:{Count}", count); } catch (Exception ex) { Console.WriteLine(ex.Message); } - Thread.Sleep(50); + await Task.Delay(1000); } } } @@ -212,9 +215,12 @@ namespace Demo.AutoExpandByDate ```c# using EFCore.Sharding; using EFCore.Sharding.Tests; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using System; using System.Diagnostics; using System.Linq; +using System.Linq.Expressions; namespace Demo.Performance { @@ -222,44 +228,56 @@ namespace Demo.Performance { static void Main(string[] args) { - ShardingConfig.Init(config => + ServiceCollection services = new ServiceCollection(); + services.AddEFCoreSharding(config => { - config.AddAbsDb(DatabaseType.SqlServer) - .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1) - .AddPhysicDbGroup() - .SetHashModShardingRule(nameof(Base_UnitTest.Id), 3); - }); + config.UseDatabase(Config.CONSTRING1, DatabaseType.SqlServer); + + //添加数据源 + config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer); - DateTime time1 = DateTime.Now; - DateTime time2 = DateTime.Now; + //对3取模分表 + config.SetHashModSharding(nameof(Base_UnitTest.Id), 3); + }); + var serviceProvider = services.BuildServiceProvider(); - var db = DbFactory.GetDbAccessor(Config.CONSTRING1, DatabaseType.SqlServer); + var db = serviceProvider.GetService(); + var shardingDb = serviceProvider.GetService(); Stopwatch watch = new Stopwatch(); + Expression> where = x => EF.Functions.Like(x.UserName, $"%00001C22-8DD2-4D47-B500-407554B099AB%"); + var q = db.GetIQueryable() - .Where(x => x.UserName.Contains("00001C22-8DD2-4D47-B500-407554B099AB")) + .Where(where) + .OrderByDescending(x => x.Id) + .Skip(0) + .Take(30); + var shardingQ = shardingDb.GetIShardingQueryable() + .Where(where) .OrderByDescending(x => x.Id) .Skip(0) .Take(30); + //先执行一次预热 q.ToList(); - q.ToSharding().ToList(); + shardingQ.ToList(); + watch.Restart(); var list1 = q.ToList(); watch.Stop(); Console.WriteLine($"未分表耗时:{watch.ElapsedMilliseconds}ms"); watch.Restart(); - var list2 = q.ToSharding().ToList(); + var list2 = shardingQ.ToList(); watch.Stop(); Console.WriteLine($"分表后耗时:{watch.ElapsedMilliseconds}ms"); Console.WriteLine("完成"); - Console.ReadLine(); } } } + ``` 分表Base_UnitTest_0-2各有100万数据,然后将这三张表的数据导入Base_UnitTest中(即Base_UnitTest表的数据与Base_UnitTest_0-2三张表总合数据一致) @@ -272,84 +290,11 @@ namespace Demo.Performance ## 其它简单操作(非Sharing) 框架不仅支持Sharing,而且封装了常用数据库操作,使用比较简单 -详细使用方式参考 [链接](https://github.com/Coldairarrow/EFCore.Sharding/blob/master/examples/Demo.DI/Program.cs) - -# 常用配置 -## 多主键支持 -在实体类上加上EFCore.Sharding.DataAnnotations.Keys特性即可 -自动建表时会自动创建主键 -```c# - /// - /// 单元测试表 - /// - [Table("Base_UnitTest")] - [Index(false, nameof(CreateTime))] - [Index(false, nameof(Age))] - [Keys(nameof(Id), nameof(UserName))] - public class Base_UnitTest - { - /// - /// 代理主键 - /// - [Key, StringLength(50)] - public String Id { get; set; } - - /// - /// 创建时间 - /// - public DateTime CreateTime { get; set; } - - /// - /// 用户名 - /// - public String UserName { get; set; } - - /// - /// Age - /// - public Int32? Age { get; set; } - } - -``` +详细使用方式参考 [链接](https://github.com/Coldairarrow/EFCore.Sharding/blob/master/src/EFCore.Sharding.Tests/DbAccessor/DbAccessorTest.cs) -## 索引支持 -在实体类上加上EFCore.Sharding.DataAnnotations.Index特性即可 -可以设置多个Index特性 -自动建表时会自动创建索引 - -```c# - /// - /// 单元测试表 - /// - [Table("Base_UnitTest")] - [Index(false, nameof(CreateTime))] - [Index(false, nameof(Age))] - [Keys(nameof(Id), nameof(UserName))] - public class Base_UnitTest - { - /// - /// 代理主键 - /// - [Key, StringLength(50)] - public String Id { get; set; } - - /// - /// 创建时间 - /// - public DateTime CreateTime { get; set; } - - /// - /// 用户名 - /// - public String UserName { get; set; } - - /// - /// Age - /// - public Int32? Age { get; set; } - } - -``` +# 高级配置 +多主键、索引等高级配置请使用**IEntityTypeConfiguration** +参考[fluentApi](https://www.learnentityframeworkcore.com/configuration/fluent-api) # 注意事项