zoukankan      html  css  js  c++  java
  • .Net orm 开源项目 FreeSql 2.0.0(一张满意的答卷)

    写在开头

    2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉。

    两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息)。

    今天 FreeSql 已经很强大,感谢第一批、第二批、第N批持续提出建议的朋友,总算给社区交了一个满意答卷。

    v2.0.0 是一个稳定的版本,主要体现:

    • 用户 API 已经确定,不会轻易推翻又作调整,坚持五年不变的原则,让使用者真真正正的不再关心 ORM 使用问题;
    • 单元测试覆盖面广,5500+个单元测试,小版本更新升级无须考虑修东墙、补西墙的问题;
    • 经历两年时间的生产考验,nuget下载量已超过25万,平均每日350+;

    感叹:有些人说 .Net 陷入 orm 怪圈,动手的没几个,指点江山的一堆,.Net orm 真的如他们所讲的简单吗?

    项目简介

    温馨提醒:以下内容无商吹成份,FreeSql 不打诳语

    温馨提醒:以下内容无商吹成份,FreeSql 不打诳语

    温馨提醒:以下内容无商吹成份,FreeSql 不打诳语

    FreeSql 是 .Net ORM,能支持 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码绿色无依赖,支持新平台非常简单。目前单元测试数量:5400+,Nuget下载数量:260K+,源码几乎每天都有提交。值得高兴的是 FreeSql 加入了 ncc 开源社区:https://github.com/dotnetcore/FreeSql,加入组织之后社区责任感更大,需要更努力做好品质,为开源社区出一份力。

    QQ群:4336577(已满)、8578575(在线)、52508226(在线)

    为什么要重复造轮子?

    FreeSql 主要优势在于易用性上,基本是开箱即用,在不同数据库之间切换兼容性比较好。作者花了大量的时间精力在这个项目,肯请您花半小时了解下项目,谢谢。FreeSql 整体的功能特性如下:

    • 支持 CodeFirst 对比结构变化迁移;
    • 支持 DbFirst 从数据库导入实体类;
    • 支持 丰富的表达式函数,自定义解析;
    • 支持 批量添加、批量更新、BulkCopy;
    • 支持 导航属性,贪婪加载、延时加载、级联保存;
    • 支持 读写分离、分表分库,租户设计;
    • 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/MsAccess Ado.net 实现包,以及 Odbc 的专门实现包;

    5500+个单元测试作为基调,支持10多数数据库,我们提供了通用Odbc理论上支持所有数据库,目前已知有群友使用 FreeSql 操作华为高斯、mycat、tidb 等数据库。

    安装时选择对应的数据库包:

    dotnet add packages FreeSql.Provider.MySql
    

    CodeFirst

    FreeSql 使用 CodeFirst 模式开发,简直不要再简单,只需要如下定义:

    static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
        .UseConnectionString(FreeSql.DataType.MySql, @"Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10")
        .UseAutoSyncStructure(true) //自动同步实体结构到数据库
        .UseMonitorCommand(cmd => Console.WriteLine(cmd.CommandText + "
    ")) //打印 SQL
        .Build(); //请务必定义成 Singleton 单例模式
    

    UseAutoSyncStructure(true) 这个设置开启自动迁移功能,啥意思?如下实体类:

    class Blog {
        [Column(IsIdentity = true, IsPrimary = true)]
        public int BlogId { get; set; }
        public string Url { get; set; }
        public int Rating { get; set; }
    }
    

    fsql 对 Blog 进行 CRUD 时,比如:

    fsql.Select<Blog>().First();
    fsql.Select<Blog>().First();
    

    会执行 SQL 如下:

    CREATE TABLE IF NOT EXISTS `cccddd_mysqlconnector`.`Blog` (  
      `BlogId` INT(11) AUTO_INCREMENT, 
      `Url` VARCHAR(255), 
      `Rating` INT(11) NOT NULL, 
      PRIMARY KEY (`BlogId`)
    ) Engine=InnoDB;
    
    SELECT a.`BlogId`, a.`Url`, a.`Rating` 
    FROM `Blog` a 
    limit 0,1
    
    SELECT a.`BlogId`, a.`Url`, a.`Rating` 
    FROM `Blog` a 
    limit 0,1
    

    程序运行过程中,首次 CRUD 操作实体类会创建表,之后不再执行该操作。

    这是表不存在的情况,如果表存在的时候会怎样?会对比更新结构。FreeSql 对比表结构和实体类的差异部分,执行迁移尽量保证不丢数据(无法100%保证,请三思使用在生产环境)

    除了自动迁移功能,我们还提供以几个常用 API fsql.CodeFirst 方法:

    方法 返回值 参数 说明
    GetComparisonDDLStatements string Type 将实体类型与数据库对比,返回DDL语句
    SyncStructure bool Type 同步实体类型到数据库
    ConfigEntity ICodeFirst Action<TableFluent<T>> FluentAPI 配置实体的特性
    GetTableByEntity TableInfo Type 获取类型在ORM内部的元数据

    实体特性

    .NET ORM 几乎都是通过实体与表进行映射,怎么少得了灵活的特性设置呢。

    提示:FreeSql 可以自动识别 EFCore 实体特性 Key/Required/NotMapped/MaxLength/StringLength/DatabaseGenerated/Table/Column

    [Table(Name = "topic")]
    class Topic {
        [Column(IsPrimary = true, IsIdentity = true, Name = "id")]
        public int Id { get; set; }
    }
    

    如上 Name 设置实体类与数据库小写映射,其实还提供统一处理的方法:

    static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
        //..
        UseNameConvert(NameConvertType.ToLower)
        //..
        .Build();
    
    // PascalCaseToUnderscore: BigApple -> Big_Apple
    // PascalCaseToUnderscoreWithUpper: BigApple -> BIG_APPLE
    // PascalCaseToUnderscoreWithLower: BigApple -> big_apple
    // ToUpper: BigApple -> BIGAPPLE
    // ToLower: BigApple -> bigapple
    // 感谢【晓晨】提供的这个思路和功能
    

    CRUD

    FreeSql CRUD 命名习惯遵从 SQL,代码写起来就像写 SQL 一样,如下:

    • 插入数据:fsql.Insert(item).ExecuteAffrows();
    • 更新数据:fsql.Update<T>().Where(..).Set(..).ExecuteAffrows();
    • 删除数据:fsql.Delete<T>().Where(..).ExecuteAffrows();
    • 查询数据:fsql.Select<T>().Where(..).ToList();

    Repository

    FreeSql.Repository 作为扩展,实现了通用仓储层功能。与其他规范标准一样,仓储层也有相应的规范定义。FreeSql.Repository 参考 abp vnext 接口,定义和实现基础的仓储层(CURD),应该算比较通用的方法吧。仓储可以:

    • Select/Attach 快照对象,Update 只更新变化的字段;
    • Insert 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
    • InsertOrUpdate 插入或更新;
    • SaveMany 方法快速保存导航对象(一对多、多对多);
    • UnitOfWork 工作单元设置;

    导航属性

    微软制造了优秀的语言 c#,利用语言特性可以做一些非常好用的功能,在 ORM 中使用导航属性非常适合。

    • FreeSql ManyToOne(N对1) 提供了简单的多表 join 查询;

    • FreeSql OneToMany(1对N) 提供了简单可控的级联查询、级联保存功能;

    • FreeSql ManyToMany(多对多) 提供了简单的多对多过滤查询、级联查询、级联保存功能;

    • FreeSql 父子关系 提供了常用的 CTE查询、删除、递归功能;

    关于导航属性,我们写了一篇专门介绍的文章,可跳转查看:.NET ORM 导航属性【到底】可以解决什么问题?

    分表分库

    关于分表分库,我们写了一篇专门介绍的文章,可跳转查看:.NET ORM 分表分库【到底】怎么做?

    事务

    关于事务,我们写了一篇专门介绍的文章,可跳转查看:.NET 数据库事务的各种玩法进化

    写在最后

    FreeSql 2.0.0 他是免费自由的 ORM,也可以说是宝藏 ORM。更多文档请前往 wiki 查看。

    下一个五年,期待少年的你还能归来在此贴回复,兑现五年不变的承诺。

    多的不说了,希望民间的开源力量越来越强大。

    希望作者的努力能打动到你,请求正在使用的、善良的您能动一动小手指,把文章转发一下,让更多人知道 .NET 有这样一个好用的 ORM 存在。谢谢!!

    FreeSql 使用最宽松的开源协议 MIT https://github.com/dotnetcore/FreeSql,完全可以商用,文档齐全。QQ群:4336577(已满)、8578575(在线)、52508226(在线)

  • 相关阅读:
    获取Web打印的实际打印次数
    Web打印的在线设计
    上海交易所的STEP/FIX/FAST协议解析
    回忆我的姑妈
    指定Web打印的打印机
    Web打印控件设计
    最终用户在线设计和修改Web报表
    NOIP2021 游记
    gym103427 部分题解
    gym103428 部分题解
  • 原文地址:https://www.cnblogs.com/kellynic/p/14028615.html
Copyright © 2011-2022 走看看