(精华)2020年7月15日 ASP.NET Core EFCore分库分表框架的使用(手写版)

news/2024/4/16 3:11:39
public void ConfigureServices(IServiceCollection services)
{services.AddEFCoreSharding(config =>{单表//config.UseDatabase(Config.CONSTRING1, DatabaseType.SqlServer);使用多个数据库//config.UseDatabase<IMyDbAccessor>(Config.CONSTRING1, DatabaseType.SqlServer);//DateTime startTime = DateTime.Now.AddMinutes(-5);//DateTime endTime = DateTime.MaxValue;分表//config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库//    .AddPhysicDbGroup()//添加物理数据库组//    .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1)//添加物理数据库1//    .SetDateShardingRule<Base_UnitTest>(nameof(Base_UnitTest.CreateTime))//设置分表规则//    .AutoExpandByDate<Base_UnitTest>(//设置为按时间自动分表//        ExpandByDateMode.PerMinute,//        (startTime, endTime, ShardingConfig.DefaultDbGourpName)//        );//获取配置文件的连接字符串string conName = Configuration["ConnectionName"];//判断是否启用逻辑删除if (Configuration["LogicDelete"].ToBool())config.UseLogicDelete();//连接数据库config.UseDatabase(Configuration.GetConnectionString(conName), Configuration["DatabaseType"].ToEnum<DatabaseType>());//设置启用程序集的名称config.SetEntityAssembly(GlobalData.FXASSEMBLY_PATTERN);});
}

appsettings.json

{"LogicDelete": false, //是否开启逻辑删除,默认为物理删除"DatabaseType": "SqlServer", //默认数据库类型,定义详见EFCore.Sharding.DatabaseType"ConnectionName": "BaseDb", //默认连接字符串名"ConnectionStrings": {//SQLServer"BaseDb": "Data Source=.;Initial Catalog=Colder.Admin.AntdVue;Integrated Security=True;Pooling=true;"//PostgreSQL//"BaseDb": "SERVER=localhost;PORT=5432;DATABASE=Colder.Admin.AntdVue;USER ID=postgres;PASSWORD=postgres"//MySQl//"BaseDb": "server=127.0.0.1;user id=root;password=root;persistsecurityinfo=True;database=Colder.Admin.AntdVue;SslMode=none"//Oracle//"BaseDb": "Data Source=127.0.0.1/ORCL;User ID=COLDER.ADMIN.ANTDVUE;Password=123456;Connect Timeout=3"}
}

普通的使用方式

ShardingConfig.Init(config =>
{config.AddAbsDb(DatabaseType.SQLite).AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, "DataSource=db.db").AddPhysicDbGroup().SetHashModShardingRule<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);
});
using(IShardingDbAccessor _db = DbFactory.GetShardingDbAccessor())
{Base_UnitTest _newData  = new Base_UnitTest{Id = Guid.NewGuid().ToString(),UserId = "Admin",UserName = "超级管理员",Age = 22};List<Base_UnitTest> _insertList = new List<Base_UnitTest>{new Base_UnitTest{Id = Guid.NewGuid().ToString(),UserId = "Admin1",UserName = "超级管理员1",Age = 22},new Base_UnitTest{Id = Guid.NewGuid().ToString(),UserId = "Admin2",UserName = "超级管理员2",Age = 22}};//添加单条数据_db.Insert(_newData);//添加多条数据_db.Insert(_insertList);//清空表_db.DeleteAll<Base_UnitTest>();//删除单条数据_db.Delete(_newData);//删除多条数据_db.Delete(_insertList);//删除指定数据_db.Delete<Base_UnitTest>(x => x.UserId == "Admin2");//更新单条数据_db.Update(_newData);//更新多条数据_db.Update(_insertList);//更新单条数据指定属性_db.UpdateAny(_newData, new List<string> { "UserName", "Age" });//更新多条数据指定属性_db.UpdateAny(_insertList, new List<string> { "UserName", "Age" });//更新指定条件数据_db.UpdateWhere<Base_UnitTest>(x => x.UserId == "Admin", x =>{x.UserId = "Admin2";});//GetList获取表的所有数据var list=_db.GetList<Base_UnitTest>();//GetIQPagination获取分页后的数据var list=_db.GetIShardingQueryable<Base_UnitTest>().GetPagination(pagination);//Maxvar max=_db.GetIShardingQueryable<Base_UnitTest>().Max(x => x.Age);//Minvar min=_db.GetIShardingQueryable<Base_UnitTest>().Min(x => x.Age);//Averagevar min=_db.GetIShardingQueryable<Base_UnitTest>().Average(x => x.Age);//Countvar min=_db.GetIShardingQueryable<Base_UnitTest>().Count();//事务,使用方式与普通事务一致bool succcess = _db.RunTransaction(() =>{_db.Insert(_newData);var newData2 = _newData.DeepClone();_db.Insert(newData2);}).Success;Assert.AreEqual(succcess, false);}

按时间分表

var db = DbFactory.GetShardingDbAccessor();
while (true)
{try{db.Insert(new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = 1,UserName = Guid.NewGuid().ToString(),CreateTime = DateTime.Now});DateTime time = DateTime.Now.AddMinutes(-2);var count = db.GetIShardingQueryable<Base_UnitTest>().Where(x => x.CreateTime >= time).Count();Console.WriteLine($"当前数据量:{count}");Stopwatch watch = new Stopwatch();var q = db.GetIQueryable<Base_UnitTest>().Where(x => x.UserName.Contains("00001C22-8DD2-4D47-B500-407554B099AB")).OrderByDescending(x => x.Id).Skip(0).Take(30);q.ToList();q.ToSharding().ToList();watch.Restart();var list1 = q.ToList();watch.Stop();Console.WriteLine($"未分表耗时:{watch.ElapsedMilliseconds}ms");//7800mswatch.Restart();var list2 = q.ToSharding().ToList();watch.Stop();Console.WriteLine($"分表后耗时:{watch.ElapsedMilliseconds}ms");//2400ms}catch (Exception ex){Console.WriteLine(ex.Message);}Thread.Sleep(50);
}

备注

/// <summary>
/// 单元测试表
/// </summary>
[Table("Base_UnitTest")]
[Index(false, nameof(CreateTime))]//建表自动创建索引
[Index(false, nameof(Age))]//建表自动创建索引
[Keys(nameof(Id), nameof(UserName))]//自动建表时会自动创建主键(多主键支持)
public class Base_UnitTest
{/// <summary>/// 代理主键/// </summary>[Key, StringLength(50)]public String Id { get; set; }/// <summary>/// 创建时间/// </summary>public DateTime CreateTime { get; set; }/// <summary>/// 用户名/// </summary>public String UserName { get; set; }/// <summary>/// Age/// </summary>public Int32? Age { get; set; }
}

多数据库插入

class Program{static void Main(string[] args){Host.CreateDefaultBuilder(args).ConfigureLogging(config =>{}).ConfigureServices((host, services) =>{services.AddHostedService<DbTest>();services.UseEFCoreSharding(config =>{//单表config.UseDatabase(Config.CONSTRING1, DatabaseType.SqlServer);//使用多个数据库config.UseDatabase<IMyDbAccessor>(Config.CONSTRING1, DatabaseType.SqlServer);DateTime startTime = DateTime.Now.AddMinutes(-5);DateTime endTime = DateTime.MaxValue;//分表config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库.AddPhysicDbGroup()//添加物理数据库组.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1)//添加物理数据库1.SetDateShardingRule<Base_UnitTest>(nameof(Base_UnitTest.CreateTime))//设置分表规则.AutoExpandByDate<Base_UnitTest>(//设置为按时间自动分表ExpandByDateMode.PerMinute,(startTime, endTime, ShardingConfig.DefaultDbGourpName));});}).Build().Run();}}
public interface IMyDbAccessor : IDbAccessor{}
class DbTest : BackgroundService{readonly IServiceProvider _serviceProvider;readonly ILogger _logger;public DbTest(IServiceProvider serviceProvider, ILogger<DbTest> logger){_serviceProvider = serviceProvider;_logger = logger;}protected override async Task ExecuteAsync(CancellationToken stoppingToken){Task.Factory.StartNew(async () =>{while (true){try{using (var scop = _serviceProvider.CreateScope()){//单表var db = scop.ServiceProvider.GetService<IMyDbAccessor>();List<Base_UnitTest> insertList = new List<Base_UnitTest>();for (int i = 0; i < 100; i++){insertList.Add(new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = i,CreateTime = DateTime.Now,UserName = Guid.NewGuid().ToString()});}var single = new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = 100,CreateTime = DateTime.Now,UserName = Guid.NewGuid().ToString()};await db.InsertAsync(single);await db.InsertAsync(insertList);int count = await db.GetIQueryable<Base_UnitTest>().CountAsync();_logger.LogInformation("单表插入数据成功 当前数据量:{Count}", count);//分表var shardingDb = scop.ServiceProvider.GetService<IShardingDbAccessor>();await shardingDb.InsertAsync(single);await shardingDb.InsertAsync(insertList);count = await shardingDb.GetIShardingQueryable<Base_UnitTest>().CountAsync();_logger.LogInformation("分表插入数据成功 当前数据量:{Count}", count);}}catch (Exception ex){_logger.LogError(ex, "");}await Task.Delay(2000);}}, TaskCreationOptions.LongRunning);await Task.CompletedTask;}}

webapi的使用

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{readonly IShardingDbAccessor _shardingDbAccessor;public TestController(IShardingDbAccessor shardingDbAccessor){_shardingDbAccessor = shardingDbAccessor;}[HttpGet]public async Task<string> Get(){List<Base_UnitTest> insertList = new List<Base_UnitTest>();for (int i = 0; i < 100; i++){insertList.Add(new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = i,CreateTime = DateTime.Now,UserName = Guid.NewGuid().ToString()});}await _shardingDbAccessor.InsertAsync(insertList);return "成功";}
}

备注:非分表用IDbAccessor,分表用IShardingDbAccessor


http://www.ppmy.cn/news/625124.html

相关文章

4.哈希函数和哈希表

10.基础提升 哈希函数与哈希表等_哔哩哔哩_bilibili 的学习笔记 哈希函数f的特征&#xff1a; 相同的输入一定导致相同的输出 不同的输入 导致不同的输出&#xff08;有可能有碰撞&#xff09; 输出是均匀分布的 in—(f函数)-out —(%m取模)—新的输出在0&#xff5e;m-1上…

java递归生成目录树 返回list<T>

1&#xff0c;java递归生成目录树 返回list<T> 递归方法返回List<T>类型 public List<ProductCategory> treeselect() {// 获取数据库表中的所有数据List<ProductCategory> dataList productCategoryMapper.selectAll();log.info("dataList---…

nexus 远程代码执行 (CVE-2020-10199/CVE-2020-10204)

nexus 远程代码执行 &#xff08;CVE-2020-10199/CVE-2020-10204&#xff09; 漏洞介绍: Nexus Repository Manager&#xff08;NXRM&#xff09;是美国Sonatype公司的一款Maven仓库管理器。 CVE-2020-10199的漏洞需要普通用户权限即可触发&#xff0c;而CVE-2020-10204则需要…

达梦数据库事务管理

1.事务介绍 数据库中由用户自定义发起的一些列操作集合简称事务。只要可以连接数据库中进行一组操作序列都可以称为事务。 COMMIT 操作会将该语句所对应事务对数据库的所有更新持久化&#xff08;即写入磁盘&#xff09;&#xff0c;数据库此时进入一个新的一致性状态&#xff…

【Java】一篇文章让你了解字节码是什么

了解字节码 解读字节码&#xff08;上&#xff09; 解读字节码&#xff08;下&#xff09; 一、什么是字节码 1. 先来说一下什么是机械码 机械码就是cpu能够直接读取并运行的代码&#xff0c;它是用二进制编码表示的&#xff0c;也叫做机械指令码。在编写这种代码时&#xf…

char FAR * h_name中的FAR

FAR 是16位系统时候的概念了&#xff0c;代表远指针的意思。 近指针是16位的指针&#xff0c;它只表示段内的偏移地址&#xff0c;因而只能对64k字节数据段内地址进行存取。 如 char near *p; p(char near *)0xffff; 远指针是32位指针&#xff0c;它表示段地址&#xff1a;…

电源风扇引起的联想B500运行中死机黑屏问题

联想一体机B500,运行中出现死机,键盘电源灯长亮,黑屏,必须拔除电源后才能重新开机,发现背部散热很热,风扇有异响,打开后盖后发现,电源风扇启动后断断续续的停转,之后就彻底停止,开机后不做任何操作不会死机,运行3dmark测试,不到2分钟就当机了,拆换电源风扇后,测试运行正常

华为设备组网综合案例:有线无线用户统一接入配置案例

数据规划 Eth-Trunk1 AC&#xff1a;GE1/0/2&#xff0c;GE1/0/4加入Eth-Trunk1。S5700-1&#xff1a;GE0/0/1&#xff0c;GE0/0/4加入Eth-Trunk1&#xff0c;AC与接入交换机之间&#xff0c;配置Eth-Trunk1以增加&#xff0c;网络带宽&#xff0c;并提高网络可靠性&#xff1b…

与哈希函数有关的结构

文章目录 一、哈希函数的特性二、哈希表的增删改查为什么是O(1)三、布隆过滤器四、一致性哈希1.引入2.原理3.虚拟结点技术4.管理负载 一、哈希函数的特性 1.哈希函数的输入域是无穷大的&#xff0c;而输出域是相对有限的&#xff0c;但是也可以非常大。如&#xff1a;0~2的64次…

对堆栈8字节对齐问题的讨论

目录 一、字节对齐原则 二、为什么要保证堆栈8字节对齐 三、编译器为我们做了什么 四、os下应该怎样设置任务堆栈 五、Cortex-M3 内核为我们做了什么 六、总结 七、使用系统时的操作(uCOS-Ⅲ) 一、字节对齐原则 &#xff11;、结构(struct)(或联合(union)) 中的第一个数…

phoenix(BIOS) NVRM 的数据结构 bios(逆向工程)

header 7 sig NAPI 4 byte offset next data 2 byte magic code 1 byte 然后是8个字节 如 Extended System Configuration Data "ESCD" dwoffetset dw offsetlength csRestoreMemConfigFromEscdJ proc far ; CODE XRE…

网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址?

网站配置了Cloudflare代理后&#xff0c;如何配置Nginx获取的真实客户端IP地址&#xff1f; 这是一个很简单的问题&#xff0c;如何在后台获取真实的访问者IP地址&#xff1f; 网站为了避免有些不怀好意的访问者&#xff0c;不得不自动分析一下客户端访问信息&#xff0c;比如同…

【嵌入式】堆栈8字节对齐

本文转载于: https://www.cnblogs.com/sky1991/archive/2012/10/13/2722482.html 并且自己稍微做了修改 一、为什么要保证堆栈8字节对齐 AAPCS规则要求堆栈保持8字节对齐。 如果不对齐&#xff0c;调用一般的函数也是没问题的。但是当调用需要严格遵守AAPCS规则的函数时可能会…

华为VXLAN集中式网关部署实验——BGP 动态方式

文章目录 实现拓扑图步骤一&#xff1a;实验前准备步骤二&#xff1a;设备配置步骤三&#xff1a;配置验证 实现拓扑图 步骤一&#xff1a;实验前准备 ​ 本实验使用的是eNSP v1.2.00.500&#xff0c;CE12800系统版本Version 8.130 (CE12800 V800R013C00SPC560B560)&#xff0…

eNSP40、41错误解决方案,按照这些方法解决一般都能成功,分享给小伙伴们

注明&#xff1a;本文并非原创&#xff0c;在原文的基础上加了一些自己遇到的一些问题解决方法&#xff0c;如果还不太清楚&#xff0c;可以查看原文&#xff0c;出自&#xff1a;https://forum.huawei.com/enterprise/zh/thread-449489.html 1、重新安装ENSP的所有组件&#…

Linux pg打桩(1)单线程

pg打桩调试技术在调用每个函数中增加一个计数器&#xff0c;来统计函数的调用顺序&#xff0c;待进程崩溃时打印出函数的调用顺序进行问题定位分析。 代码 arm-linux-gnueabihf-gcc -c arm_mcount.c -o arm_mcount.o arm-linux-gnueabihf-gcc -pg arm_mcount.o main.c -o tt 不…

如何用电子表格计算考试成绩各科前20名均分,计算机合格率?

假设某科成绩在B2:B500&#xff0c;则该科前20名的均分为&#xff1a; average(if(b2:b500>large(b2:b500,20),b2:b500)) 按ctrlshiftenter三键结束。 假设及格分为60分&#xff0c;则该科及格率为&#xff1a; countif(b2:b500,">60")/count(b2:b500) 可以设置…

最全华为ensp路由器启动失败错误代码40怎么办?

华为ensp路由器启动失败错误代码40怎么办&#xff1f; 2020-10-21 分类&#xff1a;使用教程 阅读(224) 评论(0) eNSP模拟器常常会出现路由器启动失败的情况&#xff0c;错误代码&#xff1a;40&#xff0c;这到底是怎么样的情况呢&#xff1f; 59学习网整理了有关的解答&am…

【嵌入式笔记】简要谈一谈嵌入式开发中重写printf的几种方法

文章目录 抛砖引玉1 宏定义替换2 直接重写printf函数的实现3 重写fputc/putchar接口4 仿照POSIX的实现&#xff0c;从文件描述符0/1/2上面做文章 总结更多分享 摘要 简单总结了一下几种重写printf的方法&#xff0c;有兴趣的可以参与讨论讨论。 抛砖引玉 我大概查阅并考证了一…

优漫动游:文凭对于UI设计来说相当什么?

文凭对于UI设计来说相当什么?随着我们生活在一个不断变化&#xff0c;世界也随之不断发展变化。许多人都知道&#xff0c;随着世界人口和年龄的增长&#xff0c;我们的知识和技能不断减少。这意味着我们必须学习新的知识才能在我们不需要之前能够生活和工作的地方。但是&#…
最新文章