ORM-EFCore.Sharding

[删除(380066935@qq.com或微信通知)]

Coldairarrow/EFCore.Sharding: Database Sharding For EFCore (github.com)


简介

本框架旨在为EF Core提供Sharding(即读写分离分库分表)支持,不仅提供了一套强大的普通数据操作接口,并且降低了分表难度,支持按时间自动分表扩容,提供的操作接口简洁统一.



引言

读写分离分库分表一直是数据库领域中的重难点,当数据规模达到单库极限的时候,就不得不考虑分表方案。EF Core作为.NET Core中最为主流的ORM,用起来十分方便快捷,但是官方并没有相应的Sharding支持,鄙人不才,经过一番摸索之后终于完成这个框架.


开始

准备

首先根据需要安装对应的Nuget包 最新版基于EFCore5,若需要使用EFCore3请使用EFCore3.Sharding


包名 说明

EFCore.Sharding 必装包

EFCore.Sharding.MySql MySql支持

EFCore.Sharding.PostgreSql PostgreSql支持

EFCore.Sharding.SQLite SQLite支持

EFCore.Sharding.SqlServer SqlServer支持

EFCore.Sharding.Oracle Oracle支持

EFCore3.Sharding 必装包

EFCore3.Sharding.MySql MySql支持

EFCore3.Sharding.PostgreSql PostgreSql支持

EFCore3.Sharding.SQLite SQLite支持

EFCore3.Sharding.SqlServer SqlServer支持

EFCore3.Sharding.Oracle Oracle支持

配置

ServiceCollection services = new ServiceCollection();

//配置初始化

services.AddEFCoreSharding(config =>

{

    //添加数据源

    config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer);


    //对3取模分表

    config.SetHashModSharding<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);

});

上述代码中完成了Sharding配置


AddEFCoreSharding注入EFCoreSharding

AddDataSource添加分表数据源

SetHashModSharding是采用哈希取模的分表规则,分表字段为Id,取模值为3,会自动生成表Base_UnitTest_0,Base_UnitTest_1,Base_UnitTest_2

使用

配置完成,下面开始使用,使用方式非常简单,与平常使用基本一致

首先通过注入获取到IShardingDbAccessor


var db=ServiceProvider.GetService<IShardingDbAccessor>();

然后即可进行数据操作:


Base_UnitTest _newData  = new Base_UnitTest

{

    Id = Guid.NewGuid().ToString(),

    UserId = "Admin",

    UserName = "超级管理员",

    Age = 22

};

List<Base_UnitTest> _insertList = new List<Base_UnitTest>

{

    new Base_UnitTest

    {

        Id = Guid.NewGuid().ToString(),

        UserId = "Admin1",

        UserName = "超级管理员1",

        Age = 22

    },

    new Base_UnitTest

    {

        Id = Guid.NewGuid().ToString(),

        UserId = "Admin2",

        UserName = "超级管理员2",

        Age = 22

    }

};

//添加单条数据

_db.Insert(_newData);

//添加多条数据

_db.Insert(_insertList);

//清空表

_db.DeleteAll<Base_UnitTest>();

//删除单条数据

_db.Delete(_newData);

//删除多条数据

_db.Delete(_insertList);

//删除指定数据

_db.Delete<Base_UnitTest>(x => x.UserId == "Admin2");

//更新单条数据

_db.Update(_newData);

//更新多条数据

_db.Update(_insertList);

//更新单条数据指定属性

_db.Update(_newData, new List<string> { "UserName", "Age" });

//更新多条数据指定属性

_db.Update(_insertList, new List<string> { "UserName", "Age" });

//更新指定条件数据

_db.Update<Base_UnitTest>(x => x.UserId == "Admin", x =>

{

    x.UserId = "Admin2";

});

//GetList获取表的所有数据

var list=_db.GetList<Base_UnitTest>();

//Max

var max=_db.GetIShardingQueryable<Base_UnitTest>().Max(x => x.Age);

//Min

var min=_db.GetIShardingQueryable<Base_UnitTest>().Min(x => x.Age);

//Average

var min=_db.GetIShardingQueryable<Base_UnitTest>().Average(x => x.Age);

//Count

var min=_db.GetIShardingQueryable<Base_UnitTest>().Count();

//事务,使用方式与普通事务一致

bool succcess = _db.RunTransaction(() =>

{

    _db.Insert(_newData);

    var newData2 = _newData.DeepClone();

    _db.Insert(newData2);

}).Success;

Assert.AreEqual(succcess, false);

上述操作中表面上是操作Base_UnitTest表,实际上却在按照一定规则使用Base_UnitTest_0~2三张表,使分片对业务操作透明,极大提高开发效率