EF Core3.X实现水平分表
时间:2021-08-11
本文章向大家介绍EF Core3.X实现水平分表,主要包括EF Core3.X实现水平分表使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
DataAccessHelper
一个基于EFCore的工具类,对EFCore中的context操作做了进一步的封装,且支持一个实体类映射多个数据表。
使用方法
如Demo中的例子所示,示例程序中一个Post实体类对应有多个Post数据表,多个数据表按年月存放不同的数据。数据表的命名规则为PostyyyyMM(如Post201910)。
1.新建数据表命名规则提供类,实现ITableMappable接口
// 数据表命名规则提供类,用于根据不同的条件映射不同的数据表 public class PostMapper : ITableMappable { // 根据条件返回对应的数据表名 public string GetMappingTableName(Type modelType, object condition) { string ret = ""; if (condition is DateTime date) { if (modelType == typeof(Post)) { // Format like Post201906 ret = $"Post{date.ToString("yyyyMM")}"; } } return ret; } }
2.你的DbContext类需要改动一些代码
请将你代码中的派生自DbContext类改为派生自ExtendDbContext,ExtendDbContext几乎不会改变任何DbContext的行为。
- 将你代码中的派生自DbContext类改为派生自ExtendDbContext
- 实现基类的构造方法,但可以什么都不干
- 把重写OnConfiguring的代码移到Configuring方法中进行重写
- 把重写OnModelCreating的代码移到ModelCreating方法中进行重写
// step1:派生自ExtendDbContext public partial class BloggingContext : ExtendDbContext { public virtual DbSet<Blog> Blog { get; set; } public virtual DbSet<Post> Post { get; set; } // step2:实现基类的构造方法,但可以什么都不干 public BloggingContext() { } // step2:实现基类的构造方法,但可以什么都不干 public BloggingContext(ICollection<TableMappingRule> rules):base(rules) { } private static string ConnectString { get; set; } public static void SetConnectString(string conStr) { ConnectString = conStr; } // step3:把重写OnConfiguring的代码移到Configuring方法中进行重写 protected override void Configuring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlite(ConnectString) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); } } // step4:把重写OnModelCreating的代码移到ModelCreating方法中进行重写 protected override void ModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>(entity => { entity.HasKey(e => e.BlogId); entity.ToTable("Blog"); entity.Property(e => e.BlogId).ValueGeneratedNever(); entity.Property(e => e.Url).HasColumnType("VARCHAR (1024)"); }); modelBuilder.Entity<Post>(entity => { entity.HasKey(e => e.PostId); entity.ToTable("Post"); entity.Property(e => e.PostId).ValueGeneratedNever(); entity.Property(e => e.Content).HasColumnType("VARCHAR (1024)"); entity.Property(e => e.PostDate) .IsRequired() .HasColumnType("DATETIME"); entity.Property(e => e.Title).HasColumnType("VARCHAR (512)"); entity.HasOne(e => e.Blog) .WithMany(b => b.Posts) .HasForeignKey(e => e.BlogId); }); } }
3.正式使用
// 使用示例 static void TestChangeTable(DataAccessor dal, ITableMappable mapper) { // 数据表映射条件 DateTime sept = DateTime.Parse("2019-09-05"); DateTime oct = DateTime.Parse("2019-10-05"); // 切换Post实体类的映射的数据表,切换条件为2019年10月,理论上应该切换为数据表 "Post201910" dal.ChangeMappingTable(typeof(Post), mapper, oct); // 查询该表下的所有数据 List<Post> octData = dal.GetAll<Post>().ToList(); Console.WriteLine("Oct. data"); foreach (Post item in octData) { Console.WriteLine(item); } // 切换Post实体类的映射的数据表,切换条件为2019年9月,理论上应该切换为数据表 "Post201909" dal.ChangeMappingTable(typeof(Post), mapper, sept); // 查询该表下的所有数据 List<Post> septData = dal.GetAll<Post>().ToList(); Console.WriteLine("Sept. data"); foreach (Post item in septData) { Console.WriteLine(item); } }
转载自:https://github.com/YinRunhao/DataAccessHelper/tree/EFCore31
原文地址:https://www.cnblogs.com/bihuijia/p/15129006.html
- [WCF安全系列]绑定、安全模式与客户端凭证类型:WSHttpBinding与WSDualHttpBinding
- Python中list的遍历
- Python中的参数传递与解析
- [WCF安全系列]实例演示:TLS/SSL在WCF中的应用[HTTPS]
- QEMU3 - 使用ceph来存储QEMU镜像
- Redis错误配置详解
- 顺序存储线性表的实现
- 技术揭秘:什么是定位劫持?黑客是如何进行劫持攻击的?
- CSS概要
- 如何使用 scikit-learn 为机器学习准备文本数据
- 使用jQuery Validation插件来验证表单
- 如何用Wireshark捕获USB数据?
- QEMU 2: 参数解析
- [WCF安全系列]认证与凭证:X.509证书
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能
- Laravel框架创建路由的方法详解
- Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)
- 解决Laravel blade模板转义html标签的问题
- laravel 配置路由 api和web定义的路由的区别详解
- Flutter 实现网易云音乐字幕的代码
- Yii框架通过请求组件处理get,post请求的方法分析
- PHP实现单文件、多个单文件、多文件上传函数的封装示例
- Android自定义控件单位尺寸实现代码
- Android中socket通信的简单实现
- Thinkphp5框架使用validate实现验证功能的方法
- Android通过Java sdk的方式接入OpenCv的方法
- php+js实现的无刷新下载文件功能示例
- Android如何获取视频首帧图片
- PHP单文件上传原理及上传函数的封装操作示例