Zongsoft.Data 发布公告

很高兴我们的 ORM 数据访问框架(Zongsoft.Data)在历经两个 SaaS 产品的应用之后,今天正式宣布对外推广!
这是一个类 GraphQL 风格的 ORM(Object/Relational Mapping) 数据访问框架。

又一个轮子?

在很长时间里,.NET 阵营似乎一直缺乏一个被普遍使用的 ORM 数据访问框架,从最早的原生 ADO.NET 到舶来品 iBatis.NET 和 Hibernate.NET,后来又经历了 Linq for SQL 与 Entity Framework 的混战,可能是因为 Entity Framework 早期版本的模糊定位和反复变更的设计导致了它失之霸主之位,进而造就了一段百舸争流、群雄共逐的战国时代。在历经漫长而反复的期待、失望、纠结和痛苦之后,我终于决定动手造一个轮子。

设计理念

在开始动手之前,先确定以下基本设计原则:

  • 数据库优先(Database First)
  • 严格的 POCO/POJO 支持
  • 映射模型与代码完全隔离
  • 禁止业务层出现 SQL 和类 SQL 代码

在一个业务系统中,数据结构及其关系毋庸置疑是最底层的基础性结构,数据库应由系统架构师或开发负责人进行仔细设计 NSchema/Weakly Schema 的思潮是涂抹了蜂蜜的毒药),数据访问映射以数据库表结构关系为基石,在此之上业务层亦以概念映射模型为准绳,层级之间相互隔离。

领域模型实体避免通过注解 (标签) 来进行元数据定义,应确保严格符合 POCO/POJO 范式。通过语义化的 Schema 来声明访问的数据结构关系,禁止应用层的 SQL 和 Linq 式的类 SQL 代码可降低业务层对数据层的依赖、提升代码可维护性外,还具备更加统一可控的便利性,并为数据访问引擎的实现提供了更大的优化空间和自由度。

范例说明

下面通过三个的例子 (注:例子均基于 Zongsoft.Community 项目) 来佐证上面的部分设计理念,更多示例和阐述请参考 Zongsoft.Data 项目的 README.md 文档和 Zongsoft.Community 项目的代码。

提示: 下面的范例均基于 Zongsoft.Community 开源项目,该项目是一个完整的论坛社区的后台程序。你可能需要预先阅读一下该项目的《数据库表结构设计》文档,以便更好的理解范例代码的业务逻辑。

示例一

导航查询及导航过滤

var forums = this.DataAccess.Select<Forum>(     Condition.Equal("SiteId", this.User.SiteId) &     Condition.In("Visibility", Visibility.Internal, Visibility.Public) |     (         Condition.Equal("Visibility", Visibility.Specified) &         Condition.Exists("Users",                   Condition.Equal("UserId", this.User.UserId) &                   (                       Condition.Equal("IsModerator", true) |                       Condition.NotEqual("Permission", Permission.None)                   )         )     ),     "*, MostRecentThread{ThreadId,Title,Creator{Name,Nickname,Avatar}}" );

上述数据访问的查询方法大致生成如下SQL脚本:

SELECT     t.*,     t1.ThreadId AS 'MostRecentThread.ThreadId',     t1.Title AS 'MostRecentThread.Title',     t1.CreatorId AS 'MostRecentThread.CreatorId',     t2.UserId AS 'MostRecentThread.Creator.UserId',     t2.Name AS 'MostRecentThread.Creator.Name',     t2.Nickname AS 'MostRecentThread.Creator.Nickname',     t2.Avatar AS 'MostRecentThread.Creator.Avatar' FROM Forum t     LEFT JOIN Thread AS t1 ON         t.MostRecentThreadId=t1.ThreadId     LEFT JOIN UserProfile AS t2 ON         t1.CreatorId=t2.UserId WHERE     t.SiteId = @p1 AND     t.Visibility IN (@p2, @p3) OR     (         t.Visibility = @p4 AND         EXISTS         (             SELECT u.SiteId, u.ForumId, u.UserId             FROM ForumUser u             WHERE u.SiteId = t.SiteId AND                   u.ForumId = t.ForumId AND                   u.UserId = @p5 AND                   (                       u.IsModerator = @p6 OR                       u.Permission != @p7                   )         )     );

上述示例通过