• 一款EF Core下高性能、轻量级针对分表分库读写分离的解决方案


    前言

    今天大姚给大家分享一款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
    

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

        /// 
        /// order table
        /// 
        public class Order
        {
            /// 
            /// order Id
            /// 
            public string Id { getset; }
            /// 
            /// payer id
            /// 
            public string Payer { getset; }
            /// 
            /// pay money cent
            /// 
            public long Money { getset; }
            /// 
            /// area
            /// 
            public string Area { getset; }
            /// 
            /// order status
            /// 
            public OrderStatusEnum OrderStatus { getset; }
            /// 
            /// CreationTime
            /// 
            public DateTime CreationTime { getset; }
        }
        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 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();
                    entity.ToTable(nameof(Order));
                });
            }
            /// 
            /// empty impl if use sharding table
            /// 
            public IRouteTail RouteTail { get; set; }
        }
    
    

    第四步添加分表路由:

    /// 
    /// 创建虚拟路由
    /// 
    public class OrderVirtualTableRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<Order>
    {
        public OrderVirtualTableRoute() : base(23)
        {
        }
    
        public override void Configure(EntityMetadataTableBuilder 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 Get()
            {
                var order = await _myDbContext.Set().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技术社区微信交流群👪

  • 相关阅读:
    实现一个自定义的vue脚手架
    企业移动培训考学系统
    聚观早报 | 马斯克或将推出推特竞品;亚马逊推广“挥手付”功能
    会计制度设计
    linux并发服务器 —— IO多路复用(八)
    做个行动派吧
    钉钉小程序无法关联应用
    《痞子衡嵌入式半月刊》 第 80 期
    金仓数据库KingbaseES客户端应用参考手册--21. kbbadger
    设计模式学习笔记(九)桥接模式及其应用
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/18284750