【问题标题】:Code generator vs ORM代码生成器与 ORM
【发布时间】:2019-09-23 23:18:31
【问题描述】:

我编写了一个代码生成器,它为给定的 SQL Server/CE 数据库生成 POCO 和存储库。没什么花哨的,只有使用经典 ADO.Net 的简单 CRUD 程序。我的问题是,为什么我应该使用像 L2S/EF4 这样的 ORM 而不是自定义代码生成器? 每隔 2 或 3 年,Microsoft 就会发布一些新的数据访问框架/技术,我认识不少开发人员,他们不能总是接触到最新的技术,但他们每个人都知道经典的 ADO.Net,如何修改现有代码以及如何开发新功能。 ORM 工具是否带来了当今必须的东西,或者我可以坚持使用经典的 ADO.Net?

谢谢!

【问题讨论】:

  • 非常好的问题,在我看来。
  • 如果有其他人需要接管您的项目,他可能知道 EF4 或 NHibernate - 但很可能不是您自己开发的解决方案...如果您是独立程序员:没问题。如果您是公司团队的一员:大问题。

标签: orm ado.net code-generation


【解决方案1】:

在我构建了我的万能代码生成器的同时,我使用了缺乏适当数据处理(这导致对 ORM 的感知需求)的新语言进行了 Web 编程。从未回头。

我永远不会考虑使用 ORM 的一个原因是因为我实际上知道数据库是如何工作的,非常感谢。我不想让它看起来好像我没有使用关系数据库,我想要一些东西让我以尽可能少的工作获得数据库的力量——这永远不会是 ORM,因为那是不是他们的目的。

根据我的经验,一个好的基于字典的生成器是最真实的 D-R-Y 编程(不要重复自己),它可以让我从使用数据库的琐碎工作中解放出来,让我专注于重要的事情,在坚实的表格设计之上获得良好的商业逻辑。

编辑:还有两点:

1) 走非 ORM 路线,如果不出意外的话,孤独,因为 ORM 如此风靡一时,很难找到那些从不需要它也看不到它的人点。但是让您的技术判断来指导您。

2) 几年前,我写了一篇博客文章,“为什么我不使用 ORM”,我不会链接到它,因为它太煽动性了。一段时间后,我再次尝试理解为什么可以客观地看待 ORM 并看不到任何价值,而不会引起煽动,链接是:http://database-programmer.blogspot.com/2010/12/historical-perspective-of-orm-and.html

【讨论】:

  • 这些都是非常有效的观点!我想一些好的 ORM 越来越受欢迎是因为它们专注于解决必须开发和维护数据的两个现实的问题:一个在您的架构中指定,一个在您的应用程序逻辑中构建。我们非常了解我们的数据库——这就是为什么我们利用 SQL 使用明确的真值语句这一事实,这使得编写一个库来处理数据库通信和维护变得过于简单。最后,如果您真的只想专注于业务逻辑,ORM 可以立即帮助您。
  • 我认为 Ken 关于业务逻辑的 blog post 增加了他上面的回答。
【解决方案2】:

视情况而定;您喜欢对数据库进行无用的忙碌工作,还是希望全部生成?

说真的,对我来说,绝对没有问题。每个已知的项目都应该从 ORM 开始,对我来说,LLBLGen 是最好的。虽然它不是免费的。但它节省了大量开发数据层的时间,并提供了一个很好的结构。

真的,这是一个决定你想如何度过时间的问题。如果你看到在数据层工作的价值,由于一些你可以证明的原因,当权衡像 LLBLGen 之类的东西时,那就去做吧。但对我来说,我没有。

当然,我同意你的观点,不得不不断改变 ORM 并不理想。所以我建议你花点时间(也许几周)确定哪一个最适合你喜欢开发的风格,以及你构建项目的方式,然后去做。无论如何,现在大多数主要方法都得到了很好的支持,因此选择其中一种并对其进行标准化不会有错。

【讨论】:

  • 感谢您的回答!关于“数据库无用的忙碌工作”,我可以使用一些 ORM 尽可能快地设置 DAL。我可以花一个月的时间寻找完美的 ORM 并选择 NHibernate,但几个月后,MS 将发布 EF5,这将是下一件大事(或者不是在 6 个月之后),而且所有参与当前项目的开发人员都将拥有花一些时间来学习这个新的大事,以便成功地重构现有的代码。
  • @šljaker。第一部分是开玩笑的。但是,严肃地说,需要简单的持续维护。与生成一堆 SP(需要修改或重新生成等)的东西相比,我发现在 LLBLGen 中这更容易。我听到你在谈论新技术。这就是为什么你需要坐下来找到一个现在很好的,并且有一个你可以同意的好路径。当然,你不能让你的团队不断变化。只有在有充分理由的情况下才会改变。
【解决方案3】:

支持 ORM 的一点是编译时检查。我将使用实体框架作为示例,因为这就是我用作 ORM 的内容。

如果您需要在开发过程中更改数据库架构(删除列、表等),您可以从数据库中更新您的模型,然后进行编译。现在,引用该列或表的任何地方都显示为编译时错误,从而可以轻松捕获可能仅在运行时使用标准 ado.net 时才会注意到的错误。

要考虑的另一件事是即席查询 - 如果您只想从表中提取几列数据怎么办?使用生成的代码,您需要添加一个新的查询、填充数据的类等。使用 ORM,您可以执行类似的操作,其中为您生成一个匿名类,这样您就不必进行繁琐的工作自己创造一个。

基本上,ORM 将处理本地解决方案通常无法处理的所有边缘情况。

var q = from c in ctx.contact
        where c.contactId < 4
        select c.firstName, c.lastName;


foreach(var temp in q){
   string fullname = temp.firstName + " " + temp.LastName;
}

【讨论】:

  • šljaker 询问 ORM 与生成的代码,而不是针对临时查询
  • 确实如此,但是您总是需要运行自定义查询,由生成的代码创建的查询不会涵盖所有情况,所以我认为这里值得一提
  • 并非所有 ORM 都有“编译时检查”。
【解决方案4】:

这确实取决于您的项目要求和开发过程。 ORM 充满了许多高手并为餐桌带来了很多乐趣,但如果您只是购买一些独特的功能,您可能会发现所需的精神/身体杂物令人失望。

首先您应该知道有两种 ORM:一种将现有架构映射到应用程序逻辑(您管理架构),另一种将应用程序逻辑映射到架构(ORM 管理架构)。您最好避免使用第一种,因为它们不会减轻您必须为每个环境执行/重复大量 DBA 工作的麻烦,即除了确保所有开发人员都在运行适当的模式之外,您还必须确保他们'重新运行适当的代码。第二种可以完全抽象出您使用底层数据库的事实,因此它们可以让您专注于应用程序领域,这让开发人员很高兴。

没有 DBA,没有更多针对无法管理的远程数据库实例的本地开发工作,没有更多的跨 RDBMS 细微差别,没有更多的存储过程,没有更多带有硬编码引用的查询,没有更复杂的 SQL 迁移查询。

因此,理想情况下,您的 ORM 应该:

  • 自动为您管理数据库架构
  • 提供Active record pattern 的就地实现
  • 真的能够封装所有的业务逻辑

其他好糖:

  • 自动管理数据迁移(如果您希望本体经常更改而不是没有更改)
  • 支持生成/导入夹具

请记住,您可以像@Noon 所说的那样使用 ORM 启动任何项目,但现在如果没有它,您将无法启动每个项目。理想情况下,ORM 非常适合您希望开发人员完全控制或需要他们运行私有的本地数据库实例的项目。无论哪种方式,这都是从 ass-backwards 方法的巨大飞跃:向 DBA 提出请求,喝咖啡直到 DB 更新,希望它在一周内发生。

【讨论】:

  • 这个答案真的应该指出,当您从不再需要 DBA 中获得所有这些荣耀时,如果您的程序员不了解 DBA 所知道的项目可能会导致多重灾难。我看到的最糟糕的情况是 19 位没有数据库专家的 Java 开发人员,他们遇到的问题太多了,你会哭的。忽略数据库的工作方式,后果自负。
  • 好吧,为了清楚起见或在我被进一步否决之前,最后一段中唯一提到了 DBA 的实际角色。不言而喻,您应该永远处理您不完全理解的任何事情,因为那是明显的鲁莽行为,否则建议将是荒谬的。
  • 我个人非常不喜欢代码优先方法(“ORM 管理数据库模式”)。我从 E/R+Data -> Model 开始(如果有往返 option 就好了,至少应该有增量更改支持)。然而,模式在我的项目中有它自己的生命。
  • 这不是一个好的答案。也许它适合象牙塔科学家。 “ORM 管理数据库模式”——不,只是,不。在企业世界中,数据库的寿命比应用程序长得多。一个数据库被多个应用程序访问,这些应用程序诞生、成长和消亡,而模式则存在。架构很少属于应用程序。
【解决方案5】:

对于简单的 CRUD,如果对象代表一个表格,代码生成器可以让您直接实现目标。 ORM 变得越来越有趣,如果

  • 对象关系复杂,需要遍历对象引用,
  • 需要一些缓存机制,
  • 需要处理并发读/写,
  • 需要对表格行进行一些版本控制,
  • 必须处理继承,
  • ...

简而言之:如果您只需要表和对象之间的简单映射,那么 ORM 会很有用。因此,您需要查看 ORM 的功能列表并问自己是否需要它。

在代码生成器和成熟的 ORM 之间有另一种选择:数据映射器(如 MyBatis 以前称为 iBatis)。

【讨论】:

    猜你喜欢
    • 2010-09-09
    • 2010-09-20
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多