视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.NET Core实现分表分库、读写分离的通用 Repository功能
2020-11-27 22:34:27 责编:小采
文档

可用于:.net framework 4.6+、.net core 2.1+

定义
var fsql = new FreeSql.FreeSqlBuilder()
 .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
 .UseLogger(loggerFactory.CreateLogger<IFreeSql>())
 .UseAutoSyncStructure(true) //自动迁移实体的结构到数据库
 .Build();

过滤与验证

假设我们有User(用户)、Topic(主题)两个实体,在某领域类中定义了两个仓储:

var userRepository = fsql.GetGuidRepository<User>();
var topicRepository = fsql.GetGuidRepository<Topic>();

开发过程中,我总会担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。

var userRepository = fsql.GetGuidRepository<User>(a => a.Id == 1);
var topicRepository = fsql.GetGuidRepository<Topic>(a => a.UserId == 1);
  • 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据;
  • 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常;
  • 有朋友说这个功能像 abp 的租户,但这是更小单位的过滤+验证,确保数据安全。
    有朋友说这个功能省事,但我觉得是省心。

    分表与分库

    GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装类。

    var logRepository = fsql.GetGuidRepository<Log>(null, oldname => $"{oldname}_{DateTime.Now.ToString("YYYYMM")}");

    上面我们得到一个日志仓储实例按年月分表,使用它 CURD 最终会操作 Log_201903 表。

    注意:虽然 FreeSql 支持 CodeFirst 迁移,但不提供迁移分表,开发环境中仍然可以迁移 Log 表。

    读写分离

    FreeSql 支持数据库读写分离,本功能是客户端的读写分离行为,数据库服务器该怎么配置仍然那样配置,不受本功能影响,为了方便描术后面讲到的【读写分离】都是指客户端的功能支持。

    各种数据库的读写方案不一,数据库端开启读写分离功能后,读写分离的实现大致分为以下几种:

    1、nginx代理,配置繁琐且容易出错;

    2、中件间,如MySql可以使用MyCat,但是其他数据库怎么办?

    3、在client端支持;

    FreeSql 实现了第3种方案,支持一个【主库】多个【从库】,【从库】的查询策略为随机方式。

    若某【从库】发生故障,将切换到其他可用【从库】,若已全部不可用则使用【主库】查询。

    出现故障【从库】被隔离起来间隔性的检查可用状态,以待恢复。以 mysql 为例:

    var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + 
     "Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10";
    
    IFreeSql fsql = new FreeSql.FreeSqlBuilder()
     .UseConnectionString(FreeSql.DataType.MySql, connstr)
     .UseSlave("connectionString1", "connectionString2") //使用从数据库,支持多个
     .Build();
    
    select.Where(a => a.Id == 1).ToOne(); //读【从库】(默认)
    select.Master().WhereId(a => a.Id == 1).ToOne(); //强制读【主库】
    其他特性
  • [x] 支持 CodeFirst 迁移;
  • [x] 支持 DbFirst 从数据库导入实体类,支持三种模板生成器;
  • [x] 采用 ExpressionTree 高性能读取数据;
  • [x] 支持深入的类型映射,比如pgsql的数组类型;
  • [x] 支持丰富的表达式函数;
  • [x] 支持导航属性查询,和延时加载;
  • [x] 支持同步/异步数据库操作方法,丰富多彩的链式查询方法;
  • [x] 支持读写分离、分表分库;
  • [x] 支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite;
  • 结束语

    下载本文
    显示全文
    专题