类EF框架Chloe.ORM升级:只为更完美

时间:2022-04-23 13:36:45

扯淡

Chloe.ORM:一款轻量、高效的.NET C#数据库访问框架(ORM)。查询接口借鉴 Linq(但不支持 Linq)。借助 lambda 表达式,可以完全用面向对象的方式就能轻松执行多表连接查询、分组查询、聚合查询、插入数据、批量删除和更新等操作。

为什么叫类EF?如果看过我之前文章介绍的同学可能会了解,Chloe 的查询接口和 Linq 几乎一模一样,因为查询接口就是照搬 Linq 而来。可能有人会奇怪,为啥不自己设计一套呢?呃...这的确有过。设计之初,我也构思了一套又一套的查询接口,但后来没用。因为所谓的新“接口”,无非也就是方法名字不同,功能却都是的一样的,比如创建查询入口,EF 是 DbContext.Set<T>(),有的是 XX.From<T>(),有的是 XX.Query<T>();又比如分页,我们自己设计的话,无非就是 Limit,Page,GetPage 等这几个方法名。甚至也可以不带任何 Linq 思想创新一套全然不同的接口,一种新“语法”,但折腾来折腾去,还是没 Linq 设计的巧妙与好用。既然咱创新不了比 Linq 更好的接口,因此,我直接照搬 Linq 了。当然了,如果确实不想沾上任何 EF 或者 Linq 的影子,最好还是自己设计吧。看个人喜好,Linq 的影子足够完美,我只是选择站在巨大前人的肩膀上罢了!

Chloe.ORM 从年初投入生产使用已经半年有余,从最初蹒跚走路到现在稳健安康,经历了不少风雨改动。开源以来大家看到的都是经过无数次大大小小修改后的版本。这次改动升级,都是实际使用过程和开源后做了多数据库支持发现的一些问题与改进点,如下:

更新内容

实体增加默认主键机制

在 1.* 版本中,要求实体必须显示标记主键成员和自增列。现修改后的版本不需要了,当一个实体没显示指定主键的时候,Chloe 默认选择名为 Id 的属性作为主键列,与此同时,如果该实体也没有显示指定任何自增列并且 Id 属性为 Int16、Int32 或者 Int64 类型,则也会默认其为自增列。

给实体增加默认机制,其实我内心是拒绝的。因为我讨厌这些隐士的默认,看不到显示指定 PrimaryKey 或者打上 AutoIncreamentAttribute 标签,我心里不自在- -。之前设计框架的时候我也深度考虑过这个问题,刚开始我以为我可以接受写实体时必须显示标记主键和自增列的工作量。但,在实际生产使用过程发现,实体多起来,这重复性强,很繁琐,虽然仅仅是打两个特性的工作而已。因此,我不得不在我的个人原则上做妥协,只能默默的改了- -

参数化 Sql 中对 string 参数固定Size

在数据库中,有个执行计划的概念,在参数化的 Sql 对 string 类型参数进行固定 Size,一定程度上会提高数据库性能。在 Chloe 1.* 版本中,参数值的长度是多少,参数设置的 Size 就是多少,这个可能会影响性能,因为执行计划得不到重用。现新版本中修改将 string 类型的参数 Size 属性统一设置为 4000。

调整聚合接口 Max 和 Min

在 1.* 版本中,聚合接口 Max 和 Min 只支持对数值类型操作。在上周做公司项目开发时,有需要对日期字段进行求 Max 和 Min,发现 Chloe 不支持…好吧,我承认这接口设计的不好,或者说当时照搬 Linq 时做的不够彻底- -二话不说,改!so,现在可以 q.Max<DateTime>(a=> a.OpTime) 和 q.Min<DateTime>(a=> a.OpTime) 了~

Issues 修改

  • MySql、SQLite 数据库 Provider 的 DbContext.Insert<T>(Expression<Func<T>> body) 方法:当一个实体中存在自增列,但该列不是主键,调用该方法插入数据时,在 1.* 版本中会返回自增列值,而不是主键值,这是个 Bug(SqlServer不受影响)。在 2.* 版本中这种情况已修改为返回正确的主键值。
  • 在 1.* 版本中,执行 q.Where(a=> a.OpTime == date)  没问题,但执行类似 q.Where(a=> a.OpTime.Value.Date == date) 时会引发异常,因为解析 Lambda 表达式树时,不支持解析 a.OpTime.Value.Date,早期没考虑到这点,所以会出现异常。在最新版中已修正支持。
  • 在 1.* 版本中,DateTime.Now、DateTime.UtcNow 出现在 ==、!= 运算符两侧时,并未解析成理想的 Sql GETDATE() 和 GETUTCDATE(),而是直接求值。 在最新版中已修正该问题。
  • 在调用 Select 方法时,如果 selector 主体出现两个相同的静态方法,会出现异常,如 q.Select(a=> new { MinAge = AggregateFunctions.Min(a.Age), MinHeight = AggregateFunctions.Min(a.Height)})。在最新版中已修正支持。

做程序开发的都知道,没人能写出完美的软件,或多或少会有 Bug,只是没被发现罢了。LZ 在之前的文章吹了一波NB说 Chloe“零Bug”,并不是说它没有任何缺陷,本意是 Chloe 的问题相对很少,很少…

结语

Chloe.ORM 已经成为我们公司核心项目的持久层框架,已经完全替代了之前的 EF。开源的一个多月里,我视其如孩子,一直在完善与改进,我想把她最好的姿态展现给大家,大到一个接口,小到一行代码,一个变量。即使我正在度假中,也不忘 make her beautiful!也许,这就是开源的动力。

这次改动,版本也随之升级为 2.0,较之前的 1.* 版本又稳健了许多。接下来,Chloe 又可以继续她多数据库支持之路了。Oracle?PostgreSql?敬请期待!

Chloe.ORM 完全开源,遵循 Apache2.0 协议,托管于 GitHub,地址:https://github.com/shuxinqin/Chloe

相关介绍:http://www.cnblogs.com/so9527/p/5636216.html