网站建设的经验做法,c++可以做网站吗,枣庄市网站建设,友情链接检索数据分析#x1f680; 优质资源分享 #x1f680;
学习路线指引#xff08;点击解锁#xff09;知识定位人群定位#x1f9e1; Python实战微信订餐小程序 #x1f9e1;进阶级本课程是python flask微信小程序的完美结合#xff0c;从项目搭建到腾讯云部署上线#xff0c;打造一… 优质资源分享
学习路线指引点击解锁知识定位人群定位 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 框架。我心想着处于对自己的框架的自信,并且之前有过对abpvnex和furion等一系列框架的兼容适配的尝试原则上将只要你是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 WTMDbContextCreatorTShardingDbContext: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(server127.0.0.1;port3306;databaseshardingTest;useridroot;passwordroot;,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,server127.0.0.1;port3306;databaseshardingTest;useridroot;passwordroot;);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因为多构造函数默认不支持需要手动处理。
替换ShardingCore的DbContext创建,我们刚才写的 services.Replace(ServiceDescriptor.Singleton, WTMDbContextCreator());
再然后替换WTM的IDataContext
//这是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-coregitee地址 https://gitee.com/dotnetchina/sharding-core