搜索

Frans Bouma 认为代码先行的 ORM 是“愚蠢的”

gecimao 发表于 2019-05-03 09:36 | 查看: | 回复:

  在使用 ORM 构建基于数据库的项目时,开发者可以选择是先设计数据库表,还是先设计类或抽象模型。为了展开讨论,我们先列出 Frans Bouma 的结论:代码先行的 ORM 是愚蠢的。

  先写代码,比如实体类,与先设计表一样有问题,它们都需要反向工程来得到抽象实体定义,以创建“对方”的元素:对类进行反向工程得到抽象实体定义,然后创建表和映射,或对表进行反向工程得到类,然后创建映射,这两者是等价的。核心问题是,如果先设计类或表,就等于先得到了抽象实体定义的某个投影的最终结果:类不是从天上掉下来的,在决定了领域包含这样一个类型后,它就存在了。例如,一个“Customer”,包含给定的字段:Id、CompanyName、Address 等。

  我知道“代码先行”的整个思想来源于开发者希望编写代码,用代码来思考,然后将对象持久化到数据库中。但事实是,你持久化到数据库的并不是对象,而是它们的内容,是实体的实例。而一个实体类的实例(即一个对象)则很有可能比实体的实例包含更多的数据,所以看似存储“对象”,实则无法覆盖对象。拿序列化一个对象来打比方,我们序列化的并不是对象,而是其数据的子集,得到的结果与源并不一定匹配。在将数据反序列化为 JavaScript 对象的时候,我们还能将它视为原始的对象吗?当然不能,它是对象内部的数据,可以存在于任何地方。

  那么,当“对象”序列化成 JSON 时,数据被序列化,这没有异议。但当同样的对象序列化成表行时,对象作为一个整体被序列化,这不是更奇怪吗?如果你仍然坚信 ORM 就是持久化对象,那么另一个不使用 ORM 但使用相同数据库的应用程序,在将“对象”持久化为表行时会发生什么呢?这个应用程序(甚至可以用完全不同的语言编写)可以完全正常地读取和消费存储于表行中的实体实例,不需要知道你将其视为一个持久化的.NET 对象。因为让人惊奇的是,表行中的内容并不是持久化的对象,而是持久化的实体实例,一个抽象实体定义的实例,不是类定义的实例。

  我认为真正糟糕的是 EF 中的模型先行(Model First)。我痛恨它强制你使用的 GUI 工具。

  我最喜欢的方式是用代码先行来实现一种殊途同归的方案。我以最有意义的方式编写对象模型,再以最有意义的方式编写数据库模型,然后使用 FluentAPI 来让两者匹配。

  不过我承认,我用这种方式只是漫无目的地抛出数据库对象图,因为我告诉过管理层这个应用应该使用 NoSQL,但他们却充耳不闻(该数据模型是存储不同结构的文档,但却要求用 SQL Server)。

  代码先行真正有用的场景,是用内存 SQLite DB 或某种 LocalDB 来快速进行集成或单元测试。然后可以为测试概括而快速地重新创建数据库结构。

本文链接:http://robynlynne.com/duixiangmoxing/333.html
随机为您推荐歌词

联系我们 | 关于我们 | 网友投稿 | 版权声明 | 广告服务 | 站点统计 | 网站地图

版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright @ 2012-2013 织梦猫 版权所有  Powered by Dedecms 5.7
渝ICP备10013703号  

回顶部