.NET ORM 开源项目 FreeSql 1.0 正式版发布
1|0一、简介
FreeSql 是 .NET 平台下的对象关系映射技术(O/RM),支持 .NetCore 2.1+ 或 .NetFramework 4.0+ 或 Xamarin。
从 0.0.1 发布,历时整整一年的迭代更新,原计划元旦发布1.0,可能作者比较急提前了几天发布。其实是元旦有其他事……
本文内容从简,介绍项目的主要功能框架,以及暂时能想到的可能比较有说服力的特性。
2|0二、项目统计
主仓库解决方案共计项目:29个
单元测试:3510个
Code Issues:168个
文档Wiki:43个
Stars:1140
Forks:236
Commits:690次
Nuget主包下载量:86,568次
开源地址:https://github.com/2881099/FreeSql
3|0三、功能结构
- 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持;
- 支持 DbFirst 从数据库导入实体类;
- 支持 深入的类型映射,比如pgsql的数组类型;
- 支持 丰富的表达式函数,以及灵活的自定义解析;
- 支持 导航属性一对多、多对多贪婪加载,以及延时加载;
- 支持 读写分离、分表分库,租户设计,过滤器,乐观锁,悲观锁;
- 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access;
4|0四、CodeFirst/DbFirst
一切皆 CodeFirst,所有功能都是由实体类型,到表操作的过程。CodeFirst 【自动迁移】只需要一行代码:
在开发过程中,表结构会自动创建、或改变(不丢数据),取决于实体类的变化。
CodeFirst 提供功能丰富的特性ColumnAttribute,定义实体与表间的映射,并且支持 FluentApi 方式。如果不喜欢 ColumnAttribute 这个名字,还可以通过 AOP 设置换为 MyColumnAttribute。
DbFirst 数据表先行,许多哥们使用动软、T4模板生成实体类代码。自已处理每种数据库的字段类型,和 csharp 类型对应,比较麻烦,各大 ORM 可能还不通用。
我们提供命令行工具生成实体类,dotnet-tools,对就是它。。非常好用的工具,没有之一。
它基于 Razor 模板生成,支持自定义模板生成,意味着它远不止可以生成实体类,甚至是 IRepository 或者。。。
5|0五、导航属性
从一开始就着重导航对象的设计,支持一对多、多对多、父子关系、一对一、多对一,不夸张的说目前对导航属性处理最流弊,最容易上手的 ORM。多表查询的表达式使用非常便利,如下:
可以使用导航属性一直这样点下去。。。
级联保存,级联查询功能也必不可少,如下查询多对多:
上面的代码,如果只返回 Tags 前 5条记录,也是支持的 .IncludeMany(a => a.Tags.Take(5))
对性能有追求,还可以指定 Tags 只查询部分字段
关于 IncludeMany 不便再这过多展开介绍。。。(其实还有黑科技!)
哦,还有 FreeSql.AdminLTE 扩展包,它不属于主仓库项目,最大化利用导航属性完成通用的 CURD 后台管理功能。
流弊哒哒~~~~
6|0六、仓储模式
仓储工作单元目前是当下的流行风,在比较早的时候大约0.2版本发布了第一个仓储版本,当时参考了大量的项目设计,最终选用 abp vnext 的 IRepository 设计接口,实现通用仓储类功能。
也就是说,使用 FreeSql.Repository 你不必再自己写那些繁琐的 CURD 重复的仓储功能,不用再头疼仓储类的接口方法定义。定义标准比写代码难多了,abp vnext 的 IRepository 目前是见过最好的,木有之一!!
仓储模式都在操作实体对象,无论是更新还是删除,都是传对象。。。传传传。。。
问题1、传对象更新,意味着更新所有字段?
不会的,我们的仓储实现拥有状态管理机制,从对象查询出来的时候已经记录了拍照,当调用更新方法的时候会与之对比,计算出变化的字段,只更新变化的字段!
提示:支持乐观锁、悲观锁
问题2、状态管理是否影响性能?
不完全,因为状态管理设计在仓储实现之上,我们最原始的 IFreeSql 没有这个功能(仓储算是一种扩展包吧,但是仓储又非常有效)。仓储即用即销毁,擅用它的对比功能更新对象,不滥用没有性能问题。
有了仓储怎么会没有 UnitOfWork 呢,UnitOfWork 目前以事务的方式做了默认实现,并且它拥有实体变化跟踪记录。
7|0七、性能
1、插入测试(52个字段)
18W | 1W | 5K | 2K | 1K | 500 | 100 | 50 | |
---|---|---|---|---|---|---|---|---|
MySql 5.5 ExecuteAffrows | 55,497 | 4,953 | 2,304 | 2,554 | 1,516 | 1,572 | 265 | 184 |
SqlServer Express ExecuteAffrows | 402,355 | 24,847 | 11,465 | 4,971 | 2,437 | 915 | 138 | 88 |
SqlServer Express ExecuteSqlBulkCopy | 21,065 | 578 | 326 | 139 | 105 | 79 | 60 | 48 |
PostgreSQL 10 ExecuteAffrows | 46,756 | 3,294 | 2,269 | 1,019 | 374 | 209 | 51 | 37 |
PostgreSQL 10 ExecutePgCopy | 10,090 | 583 | 337 | 136 | 88 | 61 | 30 | 25 |
Oracle XE ExecuteAffrows | - | - | - | - | 24,528 | 10,648 | 571 | 200 |
Sqlite ExecuteAffrows | 28,554 | 1,149 | 701 | 327 | 155 | 91 | 44 | 35 |
测试结果,是在相同操作系统下进行的,并且都有预热
18W 解释:插入18万行记录,表格中的数字是执行时间(单位ms)
Oracle 插入性能不用怀疑,可能安装学生版限制较大
提醒:开源数据库测试结果比较有意义,商业数据库版本之间性能可能有较大差距
2、插入测试(10个字段)
18W | 1W | 5K | 2K | 1K | 500 | 100 | 50 | |
---|---|---|---|---|---|---|---|---|
MySql 5.5 ExecuteAffrows | 15,380 | 1,813 | 1,457 | 1,254 | 563 | 246 | 55 | 21 |
SqlServer Express ExecuteAffrows | 47,204 | 2,275 | 1,108 | 488 | 279 | 123 | 35 | 16 |
SqlServer Express ExecuteSqlBulkCopy | 4,248 | 127 | 71 | 30 | 48 | 14 | 11 | 10 |
PostgreSQL 10 ExecuteAffrows | 9,786 | 568 | 336 | 157 | 102 | 34 | 9 | 6 |
PostgreSQL 10 ExecutePgCopy | 4,081 | 167 | 93 | 39 | 21 | 12 | 4 | 2 |
Oracle XE ExecuteAffrows | - | - | - | - | 2,394 | 731 | 67 | 33 |
Sqlite ExecuteAffrows | 4,524 | 246 | 137 | 94 | 35 | 19 | 14 | 11 |
提示:已经支持了 SqlServer 数据库的 SqlBulkCopy 功能、以及 PostgreSQL 数据库的 Copy 功能
8|0八、拉姆达
非常特色的功能之一,深入细化函数解析,所支持的类型基本都可以使用对应的表达式函数,例如 日期、字符串、IN查询、数组(PostgreSQL的数组)、字典(PostgreSQL HStore)等等。
1、In查询
已优化,防止 where in 元素多过的 SQL 错误,如:
[Err] ORA-01795: maximum number of expressions in a list a 1000
原来:where id in (1..1333)
现在:where id in (1..500) or id in (501..1000) or id in (1001..1333)
2、In查询(多列)
3、自定义函数
默认已经支持了很丰富的函数解析,如果不够再自己定义:
提示:SqlServer nvarchar/varchar 已兼容表达式解析,分别解析为:N'' 和 '',优化索引执行计划
9|0九、骚操作
1、代码注释 -> 迁移到数据库
CodeFirst 支持将 c# 代码内的注释,迁移至数据库的备注。先决条件:
- 实体类所在程序集,需要开启 xml 文档功能;
- xml 文件必须与程序集同目录,且文件名:xxx.dll -> xxx.xml;
2、NoneParameter
可以设置不使用 参数化 执行 SQL 命令,方便开发调试,区别如下:
在 new FreeSqlBuilder().UseNoneParameter(true) 全局设置
在 单次 ISelect、IInsert、IDelete、IUpdate 上使用 NoneParameter() 设置单次生效
3、Dto 映射查询
用过 ProjectTo 功能吗?没用过当忽略此行。。。
有些朋友可能是先 ToList().Mapper<T>(),这样会先查询了所有字段。
Dto 映射查询支持单表/多表,这个功能可以决定只查询部分字段(不是、不是、不是先查询所有字段再到内存映射)。
规则:查找属性名,会循环内部对象 _tables(多表会增长),以 主表优先查,直到查到相同的字段。
如:A, B, C 都有 id,Dto { id, a1, a2, b1, b2 },A.id 被映射。也可以指定 id = C.id 映射。
4、WhereCascade
FreeSql 擅长多表查询,遇到像isdeleted每个表都给条件的时候,挺麻烦。WhereCascade使用后生成sql时,所有表都附上这个条件。
如:
得到的 SQL:
其中的实体可附加表达式时才生效,支持子表查询。单次查询使用的表数目越多收益越大。
5、审计 CURD
如果因为某个 sql 骚操作耗时很高,没有一个相关的审计功能,排查起来可以说无从下手。
FreeSql 支持简单的类似功能:
只需要一个事件,就可以对全局起到作用。
还有一个 CurdBefore 在执行 sql 之前触发,常用于记录日志或开发调试。
6、审计属性值
实现插入/更新时统一处理某些值,比如某属性的雪花算法值、创建时间值、甚至是业务值。
当属性的类型是 long,并且标记了 [Snowflake],并且当前值是 0,那么在插入/更新时它的值将设置为雪花id值。
说明:SnowflakeAttribute 是使用者您来定义,new Snowflake().GetId() 也是由使用者您来实现
如果命名规范,可以在 aop 里判断,if (e.Property.Name == "createtime") e.Value = DateTime.Now;
还有。。还有很多骚操作。。不便在此展开。。。
10|0十、展望 2020
2019 年支持了主流的数据库:
-
SqlServer 2000-2019,支持 row_number/offset fetch next 分页自动版本选择适配,以及其他语法的差异适配,提供 ado.net 与 odbc 两种实现方式;
-
PostgreSQL 9.4-12,完成了版本间部分差异适配,提供 ado.net 与 odbc 两种实现方式;
-
MySql 5.5、Mariadb,提供 Oracle 官方驱动、与 MySqlConnector 社区驱动,还有 odbc 实现方式;
-
Oracle 11+,提供 ado.net 与 odbc 两种实现方式;
-
Sqlite,兼容了 .net core / .net framework / xamarin 平台适配,支持 CodeFirst 开发模式,一个字爽!!!
-
MsAccess 2003-2007,提供 oledb 实现方式,支持 CodeFirst 开发模式;
-
达梦,提供 odbc 的实现方式,并且支持 DbFirst 和 CodeFirst 两种开发模式;
2020 年支持国产是重点,重心,重要的工作内容,南大通用将是下一个目标,并且已经在进行中了。
开源地址:https://github.com/2881099/FreeSql
写到最后面,感谢这一年来与 FreeSql 一直陪伴的兄弟朋友们。
__EOF__

本文链接:https://www.cnblogs.com/kellynic/p/12098419.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂