EF对象是否是业务对象?

时间:2012-08-06 12:52:30

标签: .net entity-framework orm business-objects

  

可能重复:
  Using Entity Framework entities as business objects?

我正在考虑将Entity Framework用作ORM,但在进行大量阅读后,我对EF对象的确切位置感到困惑。

我的印象是,ORM的重点是消除将对象映射到关系数据库的苦差事和复杂性。你加载你的数据库并得到一堆像魔术一样的对象。 CRUD的所有内容都是针对对象完成的。如果数据库发生更改,则更改映射但您的对象保持不变。

这意味着您将在整个系统中使用这些对象,并且它们将具有行为。它们是业务对象。这对我来说很有意义,事实上MS tells you how to add behaviour

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

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

我认为ORM的重点是自动化映射并充当后备存储的抽象?我错过了什么吗?

编辑:按行为我的意思是业务逻辑。验证,计算属性,业务方法等。

2 个答案:

答案 0 :(得分:2)

一般来说,那些说你不应该将EF生成的类用作业务层的人是正确的。

在小型应用程序中,您绝对可以直接从UI中使用EF类。

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

人们经常建议使用AutoMapper(https://github.com/AutoMapper/AutoMapper)在您的EF类和DTO类以及业务层类之间进行映射,以减少编写大量映射代码的麻烦。

我认为这绝对是您可以根据项目要求做出的决定,而且不一定是正确答案。如果您开始感到疼痛,您可以随时改变方向。与往常一样,选择最适合您项目的解决方案。

答案 1 :(得分:1)

  

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

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

  

人们说(......)[EF对象]只关注数据的持久性

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

说到这里,我一直使用实体类来处理业务逻辑。但我不再是纯粹的OO的粉丝,在具有精心分离的责任的紧密合作的对象意义上。有两个原因:

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

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

  2. (无状态)函数式编程范例的进展,Linq和其他.Net语言结构鼓励了这种范式。

  3. 所以我看到我的域模型越来越接近anemic domain models,尽管从未真正到达那里。我试图给出一些理由说明为什么现在这种情况非常明智。

相关问题