使用entity framework实体作为业务对象?

我正在使用来自Microsoft的entity frameworkO / R映射器,并将实体类(映射到数据库对象的生成类)用作业务对象。 这个可以吗? 请说明你的利弊。 在业务层和表示之间进行WCF通信的情况下,如何将这些对象作为数据成员发送?

我以这种方式使用EF,一个很好的特性是生成的实体是部分类,允许它们以一种相当受保护的方式进行扩展,以免再生问题。

也可以看看MSDN上的这个链接,它描述了EF在业务逻辑方面的一些常见的使用场景。

首先,在写这篇文章的时候,有11k个问题的观点,对于答案的缺乏以及所有应有的尊重,答案的质量,给出了一个相当直接的问题,我有点惊讶。

所以,现在我已经放了一点点,我想解决这个问题,因为我认为现在更适用于最近发布的entity frameworkCode-First。

“使用entity framework实体作为业务对象?”

在我开始之前,有几点需要澄清:

  • 当你说“业务对象”时,我的印象是,你所指的这些对象包含从简单的validation(即必需的字段)到更复杂的逻辑(即在结账上处理税收)等规则或逻辑。

  • 我不认为我可以回答你关于WCF的后续问题。 这是因为我要客观地回答你关于外汇基金作为业务对象的问题,然后主观地强迫我采取一种立场,certificate我试图真正客观地回答第一个问题的矛盾。

这就是说,到你的EF作为业务对象的问题…

“我正在使用来自Microsoft的entity frameworkO / R映射器,并使用实体类(映射到数据库对象的生成类)作为业务对象,这样好吗?

对不起,这里根本没有对错的答案。 这取决于你的目标是什么,你认为是最合理的devise,同时充分理解这样做的优缺点。

“请陈述你的利弊”

我很高兴你问! 我会很高兴回答,我希望在这里,考虑到利弊,您可以做出明智的决定,您是否相信将EF用于业务对象是“OK”。 通常情况下,我会分解利弊,使其易于“消化”,但是,我不认为这是适当的,因为我认为我们会对这样一个非常有趣的话题做出不公正的处理亲爱的我的心。

首先,让我在技术上谈一会儿…您可以使用EF对象作为您的业务对象,没有任何技术上阻止您这样做。 事实上,EF Code-First(CF)通过允许您创buildPOCO并使您能够应用数据注释以进行简单的validation以及为了更复杂的validation而实现IValidatableObject,使得这非常容易。 很酷,呃?

这是讨论的核心。

EF或任何ORM旨在支持数据pipe理。 其主要职责是数据,因此您创build的对象是以数据为中心的。 所以,如果你试图通过行为来devise你的对象,那么你手头上有一点难题。 简而言之,这个难题被称为阻抗不匹配。 画这个; 您的应用程序中有两个必需的用例:

  1. 编辑用户的屏幕
  2. 显示用户信息的只读子集的控件

如果使用EF(任何味道),或任何ORM的事情,你可能会倾向于使用相同的“用户”对象来处理保存用户的能力,以及提取用户拉取只读字段的子集。 您可能会这样做是因为几个原因之一:

  1. 像许多开发人员一样,我们在教育过程中植入了这个种子,“巩固代码”是最重要的,或者更为人所知的是DRY – 不要重复自己,因此您可以看一下代码的重复,比如属性负面的情况。
  2. 诸如EF4.1之类的ORM具有技术上的限制(以及骇人的解决方法),例如将多个POCO /对象映射到相同的数据库表,从而迫使你不顾自己的信仰。
  3. 这是一个快速而简单的方法来启动和运行应用程序
  4. 它“觉得”是正确的

这样做有好处和坏处,你可以看看这是一个积极的或消极的方式取决于你的意见。

我想如果你相信代码在行为上的规范化比你成功了很多。 通过编写单个对象来处理数据和业务用例,您可以限制代码量,从而节省时间。

我想如果你相信代码行为的规范化比你失败的更糟。 通过节省代码,您牺牲了devise对象的责任,可能会导致难以pipe理,并随之增加维护成本。

无论您的意见如何,我们大概都可以同意这个业务对象承担了多重责任,对象的行为(不是数据)是次要的。 其主要职责是pipe理数据,其次要职责是处理业务规则,既简单又复杂,涉及编辑用户,显示只读用户信息。 在面向对象devise(OOD)中,如果一个对象的devise是以其身份和行为为特征的,那么这个对象可能是一个混淆的个体,因为它不符合OOD的定义。

从技术的angular度来看,任何时候你要求用户对象都要承担大量的开销。 当只显示只读信息的一个子集时,这可能包括诸如所有属性和业务规则之类的东西。

那么所有这些与我是否应该使用EF来表示我的业务对象有什么关系呢?

那么……尽pipe在技术上是可行的,但是对于是否应该使用EF或任何ORM来表示您的业务对象,有不同的哲学(一些好,一些差)。 我给出了一个旨在上述哲学核心的概要,但是他们被Rocky Lhotka和Martin Fowler等人详细logging。

你所采取的方向很可能取决于应用程序,从哲学的angular度来看,可能取决于你有多less理想主义者或实用主义者。 也就是说,我并不是暗示一个人是理想主义者还是实用主义者,或者不是用EF来代表商业对象,它只会影响你对此的看法。

在撰写本文时,微软的迹象表明,EF的构build是为了处理业务逻辑,无论对错,它们似乎都朝着这个方向发展。 EF正在不断发展,某些技术限制正在被解除,EF最终可能被用来满足两全其美。 换句话说,最终你也许可以把蛋糕吃掉。

希望这可以帮助。

关于回答一个关于ORM的持久性无知是否荒谬的问题,考虑其背后的目的是pipe理数据。 :-)对不起,我无法抗拒!

entity framework是为了将实体对象用作业务对象而devise的,但是您应该记住,业务对象将与O / R技术以及EDM模型绑定。 在EF 1.0中,没有任何支持持久性 – 无知的情况,但在4.0中增加了支持。 如果你不想使用任何基类,你可以实现接口 。

从.NET 3.5 SP1开始,它们也应该可用作WCF服务方法中的参数和返回types,而不需要任何额外的代码。

根据我的经验,我们在应用程序的业务层中使用了EF对象,但是当我们通过WCF服务层转换到表示层时,我们将从EF对象创build视图对象。

在我们的例子中,只有视图被传递给表示层。 我们这样做是为了控制数据的呈现方式,并对来自表示层的数据进行防御性validation。

在WCF事务中使用EF对象的情况下,您将失去EF对象关联的对象上下文。 CodePlex有一些努力来帮助解决这个问题,但是我没有跟上他们的努力。

要知道我遇到的两个限制是:

  1. inheritance对象不能有导航属性 – 即如果你有一个“人”类,然后是“客户”和“供应商”那些客户和供应商不能有导航属性。

  2. 方法和计算字段(部分类中的任何内容)不通过ADO.Net数据服务传输 – 如果您还使用ADO.Net数据服务,则任何扩展entity framework对象的部分类都不会通过ADO.Net传输数据服务。

这些通常不是阻止项目(对于导航属性,我们现在只是在entity framework中不使用inheritance),但可能是您自己感兴趣的东西。 我抱着希望,未来的版本将使这两个项目。

如果失去原来的对象上下文,你不能重新附加对象吗? 你需要自己处理并发问题。

我不build议使用EF对象作为WCF的DataContract对象,因为你会非常强烈地将实体对象的实现与Web服务客户端绑定在一起,将来很难做出更改,难度越大,您计划的客户端越多。

WPF应用程序框架(WAF)的BookLibrary示例应用程序显示了如何将Model-View-ViewModel(MVVM)模式与entity framework结合使用。