EF对象是否为业务对象



可能重复:
使用实体框架实体作为业务对象?

我正在考虑使用实体框架作为ORM,但在阅读了大量内容后,我真的很困惑EF对象到底适合哪里。

我的印象是,ORM的全部目的是消除将对象映射到关系数据库的繁琐和复杂性。你加载你的数据库,得到一堆像魔术一样的对象。CRUD的东西都是针对对象完成的。如果数据库发生了更改,则会更改映射,但对象保持不变。

这意味着您将在整个系统中使用这些对象,并且它们将具有行为。它们是商业对象。这对我来说是有道理的,事实上,MS告诉你如何添加行为

然而,我读到很多人说,永远不应该使用EF对象作为业务对象,因为他们只关心数据的持久性,并且会将您的业务对象与EF结合起来。他们建议使用EF作为数据层的抽象,并将其映射到真实的业务对象。

这对我来说似乎毫无意义。当我最终仍然映射到我的业务对象时,为什么我还需要另一个抽象层?如果我必须映射EF属性,我还不如映射DB列!

我认为ORM的全部目的是自动化映射并作为后台存储的抽象?我是不是错过了什么?

编辑:我所说的行为是指业务逻辑。验证、计算属性、业务方法等。

通常,那些说不应该将EF生成的类用作业务层的人是正确的。

不过,在小型应用程序中,您肯定可以直接从UI中使用EF类。

随着应用程序的大小和功能的增长,使用UI中的EF类肯定会遇到问题:选择N+1(视图中出现延迟加载)、序列化(循环引用)、AJAX/jQuery(针对微小的更新场景通过网络发送过大的对象图)等。

人们经常推荐AutoMapper(https://github.com/AutoMapper/AutoMapper)在EF类、DTO类和业务层类之间进行映射,以减少编写大量映射代码的繁琐。

我认为这绝对是你可以根据项目需求做出的决定,不一定有正确的答案。如果你开始感到疼痛,你总是可以改变方向。和往常一样,选择对您的项目可行的最简单的解决方案。

如果数据库发生了更改,则会更改映射,但对象保持不变。

没有。Db的更改也将更改映射的实体类。但这并不意味着这些类不能用于业务逻辑。如果您使用开箱即用的EF,它将创建实体类作为partial类,因此邀请您添加自己的代码,使其不会被生成的代码覆盖。

有人说(…)[EF对象]只关心数据的持久性

我不这么认为。它们可能配备了,可以持久化到数据存储中并从数据存储中填充(就像它们首先使用数据库时一样),但这不是它们关心的问题。我们应该忽略这种添加的行为,不要在业务逻辑中使用它(这是我的观点)。对象不是持久性无知,业务逻辑应该是。

说到这里,我一直在为业务逻辑使用实体类。但我不再是纯粹OO的粉丝了,从某种意义上说,OO是一种紧密合作的对象,具有精心分离的职责。原因有二:

  1. 大多数应用程序都涉及某种业务层和带有视图模型的视图层,通过控制器层粘合在一起,并通过需要序列化的边界进行通信。所以直接调用域类的行为通常不是一种选择。因此,我倾向于在通过DTO通信的服务类或外观中编程越来越多的BL,而在直接从其他层寻址的域模型中编程的BL则越来越少。这些服务方法往往是业务逻辑的完美场所。因此,大多数时候,我使用涉及类本身数据的逻辑来扩展EF类,并且不需要与其他EF类进行任何合作。这也可以防止延迟加载异常和n+1问题。我可以展示许多示例,其中我很高兴地在服务方法中从域逻辑转移到BL,但这有点超出了这个问题的范围。

    同样,我不喜欢使用OnPropertyChanging/Changed,正如MS链接所描述的那样。我做了,它是意大利面条。它在视图模型中可能很有用,例如响应用户输入,但在域类中,设置属性应该是:设置属性。没有额外的行为会被遗忘,有一天会咬到你。

  2. (无状态)函数式编程范式的发展,受到了Linq和其他人的鼓励。网络语言结构。

因此,我看到我的领域模型正在向贫血的领域模型靠拢,尽管从未真正实现。我试着给出一些理由,说明为什么现在这样做是完全合理的。

最新更新