NetCore框架WTM的分表分库实现

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

介绍

本期主角:

  • ShardingCore 一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案,具有零依赖、零学习成本、零业务代码入侵
  • WTM WalkingTec.Mvvm框架(简称WTM)是基于.net core的快速开发框架。支持Layui(前后端不分离), React(前后端分离),VUE(前后端分离),内置代码生成器,最大程度的提高开发效率,是一款高效开发的利器。

ShardingCore最新版本针对路由有了极大性能的优化由原先的Expression改成自定义的RouteExpression去除了Compile带来的性能损耗

我不是efcore怎么办

这边肯定有小伙伴要问有没有不是efcore的,我这边很确信的和你讲有并且适应所有的ADO.NET包括sqlhelper
ShardingConnector 一款基于ado.net下的高性能分表分库解决方案目前已有demo案例,这个框架你可以认为是.Net版本的ShardingSphere但是目前仅实现了ShardingSphere-JDBC,后续我将会实现ShardingSphere-Proxy希望各位.Neter多多关注

背景

之前我不是发了一篇博客吗.Net分表分库动态化处理 下面有个小伙伴留言,希望可以让我支持一下WTM 框架。我心想着处于对自己的框架的自信,并且之前有过对abpvnexfurion等一系列框架的兼容适配的尝试,原则上将只要你是efcore那么基本上都可以支持,所以秉着尝试以下的态度这边就上手了,先说下结论就是可以支持,完美不完美不清楚因为本人这个框架用的不多不知道是否是完美适配。

原理

ShardingCore

ShardingCore的整体架构是一个壳dbcontext带多个dbcontext,壳dbcontext不进行增删改查,由内部的dbcontext自己去执行,这个因为efcore的一个对象对应一个表所限制的。我们这边把壳dbcontext称作shellDbContext,执行的dbcontext叫做executorDbContext,对于ShardingCore还有一个要求就是需要初始化启动的时候Start()Start()内部需要IServiceProvider来获取DbContext,所以说整个框架离不开ioc,那么就需要启动的时候依赖注入DbContext,又因为依赖注入如果是默认的只能允许单个构造函数。这就是ShardingCore在兼容使用的时候需要注意的地方。

WTM

WTM这边我不是很熟悉,花了大概半个小时到一个小时左右的时间,进行了代码的翻阅,大概了解了其中的实现,DbContext的创建由独立的构造函数来实现,默认通过DbContext的内部方法 OnConfiguring(DbContextOptionsBuilder optionsBuilder)来进行初始化,框架里面将DbContext抽象成了IDataContext接口,框架默IDataContext接口默认依赖注入为NullDbContext如果需要使用会自行通过反射调用构造函数参数为CS类型的那一个。整体的efcore上的一些处理通过调试代码和源码的查看基本上了解了

开始接入

创建项目

那么我们首先通过WTM生成一个脚手架的简单项目,这边生成了一个mvc的项目。

添加依赖

添加ShardingCore依赖,需要x.5.0.6+版本,x代表efcore的版本

Install-Package ShardingCore -Version 6.5.0.6

添加抽象分表DbContext

这边和AbpVNext时候继承一样,因为c#不支持多继承,好在ShardingCore是接口依赖不存在实现依赖所以任何框架都可以兼容。

public abstract class AbstractShardingFrameworkContext:FrameworkContext, IShardingDbContext, ISupportShardingReadWrite{protected IShardingDbContextExecutor ShardingDbContextExecutor{get;}public AbstractShardingFrameworkContext(CS cs): base(cs){ShardingDbContextExecutor =(IShardingDbContextExecutor)Activator.CreateInstance(typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()),this);IsExecutor = false;}public AbstractShardingFrameworkContext(string cs, DBTypeEnum dbtype): base(cs, dbtype){ShardingDbContextExecutor =(IShardingDbContextExecutor)Activator.CreateInstance(typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()),this);IsExecutor = false;}public AbstractShardingFrameworkContext(string cs, DBTypeEnum dbtype, string version = null): base(cs, dbtype, version){ShardingDbContextExecutor =(IShardingDbContextExecutor)Activator.CreateInstance(typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()),this);IsExecutor = false;}public AbstractShardingFrameworkContext(DbContextOptions options) : base(options){var wrapOptionsExtension = options.FindExtension();if (wrapOptionsExtension != null){ShardingDbContextExecutor =(IShardingDbContextExecutor)Activator.CreateInstance(typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()),this);}IsExecutor = wrapOptionsExtension == null;}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){if (this.CSName!=null){base.OnConfiguring(optionsBuilder);optionsBuilder.UseSharding();}}}

简单说一下这边实现了WTM的所有构造函数,因为ShardingCore原生需要DbContextOption,当然也是可以支持实现类由自定义DbContext,构造函数中如果使用了DbContextOption那么就是由依赖注入或者ShardingCore创建的DbContext,其余的全部是WTM创建的,所以这边都需要实现并且其余的构造函数直接设置为ShellDbContext

又因为WTM默认的创建会赋值CSName所以需要对其后续进行UseSharding处理这是ShardingCore针对ShellDbContext必须要处理的

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){if (this.CSName!=null){base.OnConfiguring(optionsBuilder);optionsBuilder.UseSharding();}}

实现DataContext

很简单只需要继承抽象类和实现IShardingTableDbContext接口即可,实现该接口才能支持分表否则仅支持分库

 public class DataContext : AbstractShardingFrameworkContext,IShardingTableDbContext
{
}

编写自定义DbContext创建

因为WTM框架的DbContext拥有多个构造函数所以需要自定义,由ShardingCore提供

代码其实很简单就是如何创建一个DbContext,因为ShardingCore默认的会校验只能拥有一个构造函数并且构造函数只能是DbContextOptions或者DbContextOptions<>

public class WTMDbContextCreator<TShardingDbContext>:IDbContextCreator where TShardingDbContext : DbContext, IShardingDbContext
{public DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions){var context = new DataContext((DbContextOptions)shardingDbContextOptions.DbContextOptions);context.RouteTail = shardingDbContextOptions.RouteTail;return context;}
}

编写分表测试类

    public class Todo{public string Id { get; set; }public string Name { get; set; }}

然后再DbContext出简单设置一下

        protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);//你用dbset也是可以的modelBuilder.Entity(e =>{e.HasKey(o => o.Id);e.ToTable(nameof(Todo));});}

添加分表路由

public class TodoRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute{public TodoRoute() : base(2, 10){}public override void Configure(EntityMetadataTableBuilder builder){builder.ShardingProperty(o => o.Id);}}

StartUp

接下来就是激动人心的时候了,首先我们说过ShardingCore需要依赖注入,由因为DbContext是多构造函数

services.AddScoped(sp =>{var dbContextOptionsBuilder = new DbContextOptionsBuilder();dbContextOptionsBuilder.UseMySql("server=127.0.0.1;port=3306;database=shardingTest;userid=root;password=root;",new MySqlServerVersion(new Version()));dbContextOptionsBuilder.UseSharding();return new DataContext(dbContextOptionsBuilder.Options);});

注意依赖注入获取的是ShellDbContext所以我们需要对其进行UseSharding()

再来我们需要配置ShardingCore

services.AddShardingConfigure().AddEntityConfig(o =>{o.CreateShardingTableOnStart = true;o.EnsureCreatedWithOutShardingTable = true;o.AddShardingTableRoute();}).AddConfig(o =>{o.AddDefaultDataSource("ds0","server=127.0.0.1;port=3306;database=shardingTest;userid=root;password=root;");o.ConfigId = "c1";o.UseShardingQuery((conn, build) =>{build.UseMySql(conn, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);});o.UseShardingTransaction((conn,build)=>build.UseMySql(conn,new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger));o.ReplaceTableEnsureManager(sp => new MySqlTableEnsureManager());}).EnsureConfig();

这边的配置就是ShardingCore很简单可以查询文档或者过往的博客

这个时候有人要说了为什么不使用AddShardingDbContext因为多构造函数默认不支持需要手动处理。

替换ShardingCoreDbContext创建,我们刚才写的

   services.Replace(ServiceDescriptor.Singleton, WTMDbContextCreator>());

再然后替换WTMIDataContext

//这是WTM的默认的需要替换掉
//services.TryAddScoped();services.Replace(ServiceDescriptor.Scoped(sp =>{return sp.GetService();}));

然后启动初始化ShardingCore

            app.ApplicationServices.GetRequiredService().Start();

编写测试demo

  public async Task Login(LoginVM vm){var dataContext = Wtm.DC;var todos = new List();for (int i = 0; i < 100; i++){var todo = new Todo();todo.Id = Guid.NewGuid().ToString("n");todo.Name = todo.Id;todos.Add(todo);}await dataContext.Set().AddRangeAsync(todos);await dataContext.SaveChangesAsync();var listAsync = await dataContext.Set().Take(2).ToListAsync();
....
}

启动运行

完美创建分表并且可以插入查询完全和使用WTM一样

最后的最后

demo地址 https://github.com/xuejmnet/ShardingWTM

您都看到这边了确定不点个star或者赞吗,一款.Net不得不学的分库分表解决方案,简单理解为sharding-jdbc在.net中的实现并且支持更多特性和更优秀的数据聚合,拥有原生性能的97%,并且无业务侵入性,支持未分片的所有efcore原生查询

  • github地址 https://github.com/xuejmnet/sharding-core
  • gitee地址 https://gitee.com/dotnetchina/sharding-core

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞

漏洞名称&#xff1a;WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞CNNVD编号&#xff1a;CNNVD-201301-458发布时间&#xff1a;2013-01-24更新时间&#xff1a;2013-01-24危害等级&#xff1a; 漏洞类型&#xff1a;跨站脚本威胁类型&#xff1a;远程CVE编号&…

SpringCloudAlibaba分布式流量控制组件Sentinel实战与源码分析(上)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

Offer是否具有法律效力?

版权声明&#xff1a;原创作品&#xff0c;同意转载&#xff0c;转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。本文地址&#xff1a; http://blog.csdn.net/jobchanceleo/archive/2008/10/17/3089644.aspx<?xml:namespace prefix o …

【单元测试框架unittest】

转载于:https://www.cnblogs.com/ppppying/p/6899750.html

MySQL 添加列,修改列,删除列 的SQL写法

ALTER TABLE&#xff1a;添加&#xff0c;修改&#xff0c;删除表的列&#xff0c;约束等表的定义。 查看列&#xff1a;desc 表名;修改表名&#xff1a;alter table t_book rename to bbb;添加列&#xff1a;alter table 表名 add column 列名 varchar(30); 试了好长时间 终于…

python项目

python实战项目&#xff1a; http://www.the5fire.com/category/python实战/ python基础教程中的十个项目: python项目练习一&#xff1a;即时标记python项目练习二&#xff1a;画幅好画python项目练习三&#xff1a;万能的XMLpython项目练习四&#xff1a;新闻聚合python项目练…

C++ 炼气期之基本结构语法中的底层逻辑

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

压缩CSS代码

function yasuoCss (s) {//压缩代码   s s.replace(/\/\*(.|\n)*?\*\//g, ""); //删除注释   s s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1");   s s.replace(/\,[\s\.\#\d]*\{/g, "{"); //容错处理   s s.replace(/;\s*;/g, ";…

优惠券的工厂与策略模式实现方案

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

自然数的公理化理论体系定义的新方法

目前&#xff0c;我们人类可通过皮亚诺的五个命题和在此基础上的三个公理来定义自然数的公理化理论体系.现在&#xff0c;我们用π来定义自然数的公理化理论体系.几年前&#xff0c;美国人用2π代替π&#xff0c;看起来&#xff0c;似乎已经非常的完美了.我也比较认同这个看起…

WP8.1学习系列(第九章)——透视Pivot开发指南

Windows Phone 8 的 Pivot 控件 2014/6/18 适用于&#xff1a;Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 Windows Phone Pivot 应用提供了一种快速管理视图或页面的方法。该方法可以用于筛选大型数据集、查看多个数据集或切换应用视图。例如&a…

PS图层混合模式中英文对照

英文 中文 原理介绍 Normal 正常 默认的模式。不和其他图层发生任何混合。 Dissolve 溶解 溶解模式产生的像素颜色来源于上下混合颜色的一个随机置换值&#xff0c;与像素的不透明度有关。 Behind 背后 只对图层的透明区域进行编辑。该种模式只有在图层的…

ESP8266 系统环境搭建

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

无线网络配置

转载于:https://www.cnblogs.com/lingxzg/archive/2013/02/09/2909606.html

Java编程之反射中的注解详解

“注解”这个词&#xff0c;可谓是在Java编程中出镜率比较高&#xff0c;而且也是一个老生常谈的话题。我们之前在聊Spring相关的东西时&#xff0c;注解是无处不在&#xff0c;之前我们简单的聊过一些“注解”的相关内容&#xff0c;比如在Spring中是如何进行“注解”组合的。…

SCCM 2012 R2实战系列之十三:辅助站点部署

由于最近几个月一直处于AD升级项目中&#xff0c;很久没有更新SCCM的技术文档了。SCCM 2012中的辅助站点部署方法还是比较特别的&#xff0c;需要注意的地方也非常多&#xff0c;今天跟大家分享辅助站点的具体部署和配置方法。1. 前提条件加入域环境 安装IIS组件安装BITS和远程…

DevOps落地实践点滴和踩坑记录-(1)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

asp中日期时间函数介绍

date() 获取日期&#xff0c;格式&#xff1a;2004-2-28 time() 获取时间&#xff0c;格式&#xff1a;22:24:59 now() 获取日期和时间 格式&#xff1a; 2005-5-2 22:37:30 ddate() 获取年份&#xff1a;year(d) 获取月份&#xff1a;month(d) 获取日子&#xff1a;day(…

2014年度优秀员工代表发言稿

2019独角兽企业重金招聘Python工程师标准>>> 尊敬的各位领导和亲爱的同事们&#xff0c;大家好&#xff01; 作为优秀员工代表在这里发言&#xff0c;我很感谢刘总、周总、李总、漆总以及公司各层领导的信任和支持&#xff01;我感到十分荣幸&#xff0c;同时也感到…

[转] 我回答了90%的面试题,为什么还被拒?

这篇文章是在买买提上 FQ看到的&#xff0c;很受启发&#xff0c;特意转载于此。 原文地址: http://www.mitbbs.com/article_t/JobHunting/32327557.html 交流面试的时候&#xff0c;经常有朋友会问一个问题&#xff1a;我正确回答了90%的面试题&#xff0c;为什么被拒&#xf…