前言

今天大姚给大家分享一款EF Core下高性能、轻量级针对分表分库读写分离的解决方案,开源(Apache License)的EF Core拓展程序包:ShardingCore。

ShardingCore项目介绍

ShardingCore是一款开源、简单易用、高性能、普适性,针对EF Core生态下的分表分库的扩展解决方案,支持EF Core2+的所有版本,支持EF Core2+的所有数据库、支持自定义路由、动态路由、高性能分页、读写分离的一款EF Core拓展程序包,一款零依赖第三方组件的扩展。

ShardingCore项目特性

  • 零依赖、零学习成本、零业务代码入侵。
  • 支持EF Core的Code First支持表结构的迁移自动化。
  • 支持对数据分表/分库的自定义路由,可以满足几乎90%的业务分表/分库规则,并且支持外部传入配置。
  • 具有极少数的客户端分片中间件下才有的流式聚合,和特定的高性能分页,具有低内存高性能O(n),并且支持顺序分页,反向分页,追加排序。
  • 多数据库支持,只要是EF Core2+支持的数据库ShardingCore都是支持的。
  • 等等等...

EF Core介绍

Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术,EF Core 是适用于 .NET 的现代对象数据库映射器。它支持 LINQ 查询、更改跟踪、更新和架构迁移。EF Core 通过提供程序插件 API 与 SQL Server、Azure SQL 数据库、SQLite、Azure Cosmos DB、MySQL、PostgreSQL 和其他数据库一起使用(微软官方出品)。

值得推荐的.NET ORM框架

分享了一些比较好用且优秀的.NET ORM框架:https://mp.weixin.qq.com/s/B47HvbELB-Z-nAY8TxE15g

快速上手AspNetCore

快速上手示例来源于项目官方文档教程(更多详情请前往项目官方文档地址查阅):https://xuejmnet.github.io/sharding-core-doc/guide/quick-start-aspnetcore

5步实现按月分表,且支持自动化建表建库。

第一步安装NuGet包依赖:

ShardingCore NuGet包安装:

# 请对应安装您需要的版本
PM> Install-Package ShardingCore

使用SqlServer安装如下NuGet包:

PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer

使用MySql安装如下NuGet包:

PM> Install-Package Pomelo.EntityFrameworkCore.MySql

第二步创建查询对象模型:

    /// <summary>
    /// order table
    /// </summary>
    public class Order
    {
        /// <summary>
        /// order Id
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// payer id
        /// </summary>
        public string Payer { get; set; }
        /// <summary>
        /// pay money cent
        /// </summary>
        public long Money { get; set; }
        /// <summary>
        /// area
        /// </summary>
        public string Area { get; set; }
        /// <summary>
        /// order status
        /// </summary>
        public OrderStatusEnum OrderStatus { get; set; }
        /// <summary>
        /// CreationTime
        /// </summary>
        public DateTime CreationTime { get; set; }
    }
    public enum OrderStatusEnum
    {
        NoPay=1,
        Paying=2,
        Payed=3,
        PayFail=4
    }

第三步创建dbcontext:

dbcontext AbstractShardingDbContext和IShardingTableDbContext如果你是普通的DbContext那么就继承AbstractShardingDbContext需要分表就实现IShardingTableDbContext,如果只有分库可以不实现IShardingTableDbContext接口。


    public class MyDbContext:AbstractShardingDbContext,IShardingTableDbContext
    {
        public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Order>(entity =>
            {
                entity.HasKey(o => o.Id);
                entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o=>o.Payer).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o => o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o => o.OrderStatus).HasConversion<int>();
                entity.ToTable(nameof(Order));
            });
        }
        /// <summary>
        /// empty impl if use sharding table
        /// </summary>
        public IRouteTail RouteTail { get; set; }
    }

第四步添加分表路由:

/// <summary>
/// 创建虚拟路由
/// </summary>
public class OrderVirtualTableRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<Order>
{
    public OrderVirtualTableRoute() : base(2, 3)
    {
    }

    public override void Configure(EntityMetadataTableBuilder<Order> builder)
    {
        builder.ShardingProperty(o => o.Id);
        builder.AutoCreateTable(null);
        builder.TableSeparator("_");
    }
}

第五步配置启动项:

无论你是何种数据库只需要修改AddDefaultDataSource里面的链接字符串 请不要修改委托内部的UseXXX参数 conStr and connection。


        public void ConfigureServices(IServiceCollection services)
        {

            //添加分片配置
            services.AddShardingDbContext<MyDbContext>()
                .UseRouteConfig(op =>
                {
                    op.AddShardingTableRoute<OrderVirtualTableRoute>();
                }).UseConfig((sp,op) =>
                {
                    
                    op.UseShardingQuery((conn, builder) =>
                    {
                        builder.UseSqlServer(conn);
                    });
                    op.UseShardingTransaction((conn, builder) =>
                    {
                        builder.UseSqlServer(conn);
                    });
                    op.AddDefaultDataSource(Guid.NewGuid().ToString("n"),
                        "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;");
                }).AddShardingCore();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            
            //not required, enable check table missing and auto create,非必须  启动检查缺少的表并且创建
            app.ApplicationServices.UseAutoTryCompensateTable();
            // other configure....
        }

这样所有的配置就完成了你可以愉快地对Order表进行取模分表了:

[Route("api/[controller]")]
public class ValuesController : Controller
{
        private readonly MyDbContext _myDbContext;

        public ValuesController(MyDbContext myDbContext)
        {
            _myDbContext = myDbContext;
        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            var order = await _myDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == "2");
            return OK(order)
        }
}

项目源码地址

更多项目实用功能和特性欢迎前往项目开源地址查看,别忘了给项目一个Star支持。

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
  • 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。

欢迎加入DotNetGuide技术社区微信交流群

一款EF Core下高性能、轻量级针对分表分库读写分离的解决方案的更多相关文章

  1. efcore在Saas系统下多租户零脚本分表分库读写分离解决方案

    efcore在Saas系统下多租户零脚本分表分库读写分离解决方案 ## 介绍 本文ShardinfCore版本x.6.0.20+ 本期主角: - [`ShardingCore`](https://gi ...

  2. 分库分表、读写分离——用Sql和ORM(EF)来实现

    分库:将海量数据分成多个库保存,比如:2017年的订单库——Order2017,2018年的订单库——Order2018... 分表:水平分表(Order拆成Order1.....12).垂直分表(O ...

  3. .Net 下高性能分表分库组件-连接模式原理

    ShardingCore ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业务代码入侵. Github Source Code 助 ...

  4. .Net下你不得不看的分表分库解决方案-多字段分片

    .Net下你不得不看的分表分库解决方案-多字段分片 介绍 本期主角:ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业务代码入侵 ...

  5. efcore使用ShardingCore实现分表分库下的多租户

    efcore使用ShardingCore实现分表分库下的多租户 介绍 本期主角:ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业 ...

  6. 一款针对EF Core轻量级分表分库、读写分离的开源项目

    在项目开发中,如果数据量比较大,比如日志记录,我们往往会采用分表分库的方案:为了提升性能,把数据库查询与更新操作分开,这时候就要采用读写分离的方案. 分表分库通常包含垂直分库.垂直分表.水平分库和水平 ...

  7. “ShardingCore”是如何针对分表下的分页进行优化的

    分表情况下的分页如何优化 首先还是要给自己的开原框架打个广告 sharding-core 针对efcore 2+版本的分表组件,首先我们来快速回顾下目前市面上分表下针对分页常见的集中解决方案 分表解决 ...

  8. .NETCore 下支持分表分库、读写分离的通用 Repository

    首先声明这篇文章不是标题党,我说的这个类库是 FreeSql.Repository,它作为扩展库现实了通用仓储层功能,接口规范参考 abp vnext 定义,实现了基础的仓储层(CURD). 安装 d ...

  9. 总结下Mysql分表分库的策略及应用

    上月前面试某公司,对于mysql分表的思路,当时简要的说了下hash算法分表,以及discuz分表的思路,但是对于新增数据自增id存放的设计思想回答的不是很好(笔试+面试整个过程算是OK过了,因与个人 ...

  10. linux下mysql基于mycat做主从复制和读写分离之基础篇

    Linux下mysql基于mycat实现主从复制和读写分离1.基础设施 两台虚拟机:172.20.79.232(主) 172.20.79.233(从) 1.1软件设施 mysql5.6.39 , my ...

随机推荐

  1. ITIL4中的关键概念

    1.价值和价值共创 什么是价值 通俗表达:这有啥用? 正式表达:这能带来什么益处或起什么作用? 反问式求证: 假如没有的话,会有什么后果? 具体情境提问:如果缺少IT运维人员,业务系统会面临怎样的状况 ...

  2. Ubuntu 上安装 Docker

    步骤 1:删除任何现有的 Docker 包 但在跳到安装部分之前,有必要删除所有以前安装的 Docker. 要 卸载以前的 Docker,请使用以下命令. sudo apt remove docker ...

  3. 一个网格合并(weld)小工具

    在日常开发中会有需求合并多个Mesh网格,并且它们重合处的顶点也要合并,而并非合并成两个subMesh. 而近期刚好在学习Geomipmap的细分,需要把多个mesh块进行合并,于是写了这个脚本 (简 ...

  4. C语言:输入一个整数并让其逆反输出。123->321

    主要思想为: a)计算输入的位数有多少个 b)计算出最高位的单位(若最高位为是万位, 那么需要一个变量存储最高位数值1000) c)用取模的方法从个位数开始进行取出每一个单位上的数字 d)从个位数开始 ...

  5. NumPy 分割与搜索数组详解

    NumPy 分割数组 NumPy 提供了 np.array_split() 函数来分割数组,将一个数组拆分成多个较小的子数组. 基本用法 语法: np.array_split(array, indic ...

  6. java学习之旅(day.14)

    可变字符串 StringBuffer:可变长字符串,运行效率慢,线程安全 StringBuilder:可变长字符串,运行效率快,线程不安全 package com.zhang.lei; //Strin ...

  7. AIRIOT物联网平台助力油库自动化升级 实现业务场景全覆盖

      随着我国石油工业的飞速发展,油库规模迅速扩大,油库系统逐渐完善起来.石油行业属于高风险行业,所以石油化工产品在储存.运输和生产各个环节,均有极高的安监.环保.应急的管理要求.通常情况下,油库容量. ...

  8. 数字化开采|AIRIOT智慧矿山自动化生产解决方案

    ​ 由于矿山地形复杂,生产自动化水平低,安全监管技术落后,事故频发等很多因素对煤矿开采技术提出了数据化.可视化.智能化的要求.通过目前的煤矿开采现状可以发现煤矿开采过程中,在生产.监管.巡检.安全.效 ...

  9. 『手撕Vue-CLI』添加帮助和版本号

    前言 经过上一篇『手撕Vue-CLI』编码规范检查之后,手撕 Vue-CLI 已经进阶到了代码规范检查这一步,已经将基本的工程搭建好了,然后代码规范约束也已经加入了,并且将 nue-cli 指令绑定到 ...

  10. 一个IDEA界面如何同时打开多个项目

    第一步:先导入其中一个工程 第二步:点击File->Project Structure 第三步:导入模块 最后点击Apply即可完成一个IDEA界面同时打开多个项目的需求.