【问题标题】:Which variant of Entity Framework to use in WCF based enterprise app在基于 WCF 的企业应用程序中使用哪种实体框架变体
【发布时间】:2011-09-18 05:11:01
【问题描述】:

我们正在设计一个包含大约 100 个表和复杂业务逻辑的应用程序。 Windows 窗体将用于客户端,WCF 服务将用于服务器上的 MSSQL。

自定义 DTO 用于客户端-服务器通信,业务实体不分布式。

使用哪个实体框架变体(以及为什么):

  • EF 4.0 实体对象
  • EF 4.0 POCO
  • EF 4.1 DbContext
  • 别的东西

数据库优先方法是一项要求。

另外,是否值得实现存储库模式?这似乎有点多余,因为映射本身有一个抽象级别,而 DTO 的使用有另一个抽象级别。我目前倾向于为每个返回 IQueryable 的实体使用自动生成的可扩展存储库,只是为了有一个放置常见查询的地方,但仍然允许直接从服务层查询实体模型。

【问题讨论】:

    标签: wcf entity-framework architecture enterprise


    【解决方案1】:

    使用哪种变体?基本上,一旦您拥有自定义 DTO,唯一的问题是您是否希望控制实体代码(它们的基类)并使它们独立于 EF?你想先使用代码吗?如果所有问题的答案都是否定的,那么您可以使用 EntityObjects。如果你想让实体持久化无知或使用自定义基类,你应该去 POCO。如果您想首先使用代码或新的 DbContext API,您将需要 EF 4.1。一些相关主题:

    在设计服务层时需要考虑更多的事情。您应该注意在 WCF 中使用 EF 时必须处理的复杂情况。您的服务将向 WinForms 应用程序提供数据,并且它将以“分离模式”与它们一起使用。一旦用户完成他想做的所有更改,他就会将数据发布回服务。但问题来了——你必须告诉 EF 发生了什么变化。例如,如果您允许用户更改所有订单项目的订单(更改项目数量,添加新项目,删除一些项目)you must say EF exactly what has changed,添加了什么,删除了什么。当您使用单个实体时这很容易,但是一旦您允许用户更改对象图(尤其是多对多关系),那就很难了。最常见的解决方案是加载整个图并将来自传入 DTO 的状态合并到加载和附加的图。其他解决方案是使用 Self tracking entities 而不是 EntityObjects/POCOs + DTOs。

    在讨论存储库时,我会向您推荐this answer,它引用了许多其他讨论存储库、它们可能的冗余以及在使用它们时可能出现的错误,以使您的代码可测试。通常,只有在确实需要该层时才应添加每一层 - 因为更好地分离了关注点。

    【讨论】:

      【解决方案2】:

      POCO 的主要优点是这些类可以成为您的 DTO,因此如果您已经拥有正在使用的自定义 DTO,POCO 似乎有点多余。但是,还有一些其他优点可能对您有价值,也可能没有价值,因为您没有提到单元测试是一项要求。如果您打算编写单元测试,那么 POCO 仍然是要走的路。您可能不会注意到 4.0 POCO 和 4.1 之间有太大区别,因为您不会使用代码优先功能 (免责声明:我只使用过 4.0 POCO,所以我对任何细微差别都不太熟悉两者之间,但它们似乎或多或少是相同的——基本上我已经在 4.0 中使用 POCO,并且没有看到任何让我想要更新所有内容以使用 4.1)。

      此外,根据您是否计划对这一层进行单元测试,在使用实体框架时实现存储库/工作单元模式仍然很有价值。它用于抽象出数据访问逻辑(上下文),而不是实体本身,并允许您执行诸如在单元测试中模拟您的上下文之类的事情。我所做的是为我的上下文复制 T4 模板并使用它来创建接口,然后为上下文编辑 T4 模板并让它实现该接口并使用IObjectSet<T> 而不是ObjectSet<T>。所以而不是:

      public class MyEntitiesContext
      {
          public ObjectSet<MyClass> MyEntities
          ...
      }
      

      我最终得到:

      public interface IMyEntitiesContext
      {
          public IObjectSet<MyClass> MyEntities;
      }
      

      public class MyEntitiesContext : IMyEntitiesContext
      {
          public IObjectSet<MyClass> MyEntities
          ...
      }
      

      所以我想这真的取决于你是否打算为这一层编写单元测试。如果你不做任何需要模拟你的上下文进行测试的事情,那么最容易使用的可能是 4.0 EntityObjects,因为你不打算在层之间传递你的实体,它需要最少的努力来实施。如果您打算使用模拟,那么您可能希望使用 POCO 并实现存储库/工作单元。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        • 2013-11-27
        相关资源
        最近更新 更多