具有敏捷开发中的分层体系结构的实体框架

时间:2013-11-21 16:10:23

标签: c# asp.net-mvc entity-framework orm

我一直在使用PHP ORM,有趣一点,由于是一种动态语言:在数据访问层,我向DB发出请求,它返回一个“通用”对象(数组的好名字! )我在整个应用程序中使用它作为我的实际模型,直接在Controller和View上!令人惊讶的是一个强烈的场景!

现在在C#中,使用Entity Framework作为我的ORM,它有自己的自动生成模型(实体),我在这里提出了一个问题:

Dal (with Entity Framework) and Model layers into MVC

结论是:在应用程序中使用这些EF的实体作为我的实际模型层是错误的,因此我需要获取这些数据层模型并转换为模型层中真正的应用程序模型...在我的控制器,视图中使用来自DB的数据。

此外,我们有更多令人敬畏的问题对我有所帮助:

  1. Entity Framework in Layered Architectures
  2. In MVC, does an ORM represent the model?
  3. Entity framework and Business Layer / logic
  4. 但是我正在重新考虑在数据层中使用EF,为什么?实体框架中可爱的东西是DbContext,基本上所有的ORM都围绕它运行,如果我将这些EF的实体转换到我的模型层模型,我将浪费所有那些让事情变得更容易和更快的好东西,除了转换真正让我烦恼并使事情变得更难的课程的艰苦工作!(请不要说AutoMapper,我不能在我的工作中使用它,我不是在寻找第三方解决方案)。

    为什么在模型层或单层中使用Entity Framework更快:

      

    我会在模型层中拥有所有自动生成的模型,而我   可以在我的整个应用程序中使用它们,我也将充分利用它们   使用DbContext的所有实体框架,快速简便。

    然而,这让我感到害怕,因为我会直接在非数据层访问数据,而Controller和View可以访问所有与数据相关的内容,而且我们都知道这种方法存在的问题。

    所以我的问题是:

    我认为ORM是为了使数据访问开发更容易,更快,更简单,因为我可以使用PHP,它运行得很好。此外,我认为这对于敏捷开发来说是完美的,因为使用存储过程进行小而快的工作是一种痛苦(虽然我喜欢SP)。所以这里是实体框架和DbContext,使事情更容易,更快,对吧?但是,敏捷开发根本不打算在一起,所以这就是为什么在所有问题中我们都在谈论将EF放在数据层而不是模型层。

    但是,这使得EF的开发变得更加缓慢和痛苦,并且我们浪费了它的优势,并且认真地说,在这种情况下使用存储过程更快。 我们在分层架构中使用EF没有真正快速的开发?

4 个答案:

答案 0 :(得分:2)

我正在使用Entity Framework Code-First,而我的POCO需要符合EntityFramework的要求。我可以想到影响设计的3个方面 - 可能会有更多

  1. 我的导航属性必须实现ICollection<T>并且必须有一个setter - 所以我没有ReadOnlyCollection<T>没有setter yet

  2. 如果我想延迟加载,那么我必须将导航属性标记为virtual。延迟加载意味着实体框架将生成从实体继承的代理对象,有时也可以侵入,但如果您不想,则不必延迟加载,并且POCO将保持不受污染。

    < / LI>
  3. 使用实体框架,如果POCO有外键,生活会更容易,但如果你愿意,你也可以make do with absent foreign keys

  4. 所以我的模型不是数据访问层的一部分,只是略有影响。而且他们不需要公开有关Entity Framework的任何内容。

    我可以编写新类,添加或删除属性,更改关系,然后我可以构建数据迁移,以根据模型更改数据库。这意味着数据访问开发非常简单,非常快

    现在,您习惯于在整个应用程序中使用模型,并在MVC应用程序中使用I'm sure many people do that。您的问题不在于Entity Framework,而在于MVC。您应该问问题(as you have alreadyWhy should I use view models?并将其与您使用PHP的经验进行比较。

    为什么不使用ViewModels in your PHP controllers and Views?显然,一旦你这样做,你就不会回去了!

    因此,请使用Entity Framework快速访问数据。

    然后使用automapper快速将模型映射到视图模型 - 或者不自己在代码中映射它们 - 或者根本不使用ViewModel并继续像目前在PHP中那样进行

答案 1 :(得分:1)

当你拥有的只是一把锤子时,一切都会像钉子一样。

不要将EF或任何ORM视为旨在让一切更轻松,更快速的东西。它是一份工作的工具。 ORM的作用是弥合物理关系模型(SQL)和概念对象模型(CLR)之间的差距。它使得堆和表之间的数据移动变得更加容易。更快,就是这样。

说出你想要的AutoMapper,但同样,它是一个工作的工具。数据传输对象的概念比ORM更长。事实上,这就是你的实体课程 - DTO。它们将应用程序的一个层(概念对象模型)与另一个层(物理关系模型)之间的关注点分开。所有AutoMapper都可以简化DTO代码。它不是一个“快速修复”,它是一个有目的的工具。

现在,如果您想将实体DTO一直用于应用程序的面向外部的表面,那么您可以这样做。这可能不是一个好主意,但没有什么可以阻止你。但如果你这样做,那么我的问题是,你在谈论的“分层架构”中各层之间的分离是什么?

回复评论:

我认为你需要自己回答的问题是,更重要的是:快速,轻松地编写代码,或者拥有一个可以在新需求迫使其发展的情况下进行理智管理的分层架构。毫无疑问,除非您使用T4生成像@Paul Sinnema这样的代码,否则分层架构中会涉及更多指法。故事实现的最短距离通常是带有SqlDataSource的ASP.NET WebForm。

如果您被允许使用AutoMapper,它可能有助于编写大量繁琐的代码。不要因此而责怪EF,责怪谁让你做EF加MVC减去AutoMapper。

答案 2 :(得分:0)

将实体用作模型可能会产生意想不到的后果,包括数据丢失。考虑以下示例:

在sprint 1中,我创建了一个widget实体和一个视图来创建和编辑新的小部件(让我们称之为View1)。 widget具有以下属性:ID, prop1, prop2

在sprint 2中有一个故事要添加prop3prop4并创建一个新页面,您可以在其中编辑这些属性。假设一个与sprint 1不同的开发者得到这个故事。如果此开发人员未将prop3prop4属性添加到View1作为隐藏字段,则当有人使用View1编辑widget时,{{1 }}和prop3属性将设置为null。

如果prop4和这个新视图有自己的ViewModel映射到View1实体,那么就不会发生这种情况。

答案 3 :(得分:0)

我倾向于做的是实体是我的域模型,由应用程序中的服务执行。我为我的viewmodel创建完整的单独类,以维持2之间的SOC。