9

我使用 Entity Framework Model-FirstRepositoryUnit of Work模式,存储库返回 EF POCO。

我假设我无法向 Entity Framework 生成的 POCO 添加行为,所以我的代码现在充满了诸如XyzServicewhich 是实现 Entity Framework 生成的业务逻辑的单独类之类的东西Xyz POCO

我有以下问题:

  1. 这有一种不好的代码味道,因为我不仅有 EF POCO,而且我为每个 POCO 提供服务。除了许多类之外,业务逻辑还被拆分到业务实体之外。这是贫血反模式的一个例子吗?

  2. 如果我坚持使用 EF,有什么方法可以添加行为(即通过部分类)或其他方式?

  3. 看到使用从数据层(在我们的例子中是存储库)返回业务实体的持久无知模式,如果我想从EF-MODEL -> REPOSITORY-DAL -> BIZ-ENTITY我看到在业务实体和 EF 模型 POCO 之间会有很多双向映射。Automapper 等实用程序能否优雅地处理我可能面临的嵌套对象的复杂关系?

  4. 为了减少与其对应的 EF 模型实体重复的业务实体,我是否最好删除 EF 并使用 LINQ to SQL 为每个存储库编写我自己的存储库实现?

  5. 任何可以让我专注于代码的推荐方式(而不是像我一样首先将目标固定在 EF 模型上),然后在我准备好编写持久层时仍然使用实体框架,但避免了很多这样做的额外工作和映射?EF Code-First 在这方面会更好吗?

如果我错过了可以帮助开发的其他技术(例如 NHibernate),请随时提及。

4

4 回答 4

3
  1. 是的,根据Fowler的说法,这是一种反模式。我个人并不觉得这种反模式太冒犯,但有些人会。在这里使用最佳判断。如果感觉不对并且处理起来很痛苦,那就改变它。
  2. 的。部分课程可以帮助解决这个问题。您可以将行为放在您编写的部分中。
  3. 的,如果嵌套对象有映射设置,Automapper 将自动处理它们
  4. 再次,这取决于你。如果 EF 让您发疯,请不要使用它。使用有效的方法和让您在使用时感觉良好的方法。
  5. Code first正是为此而构建的。
于 2012-12-17T21:36:37.790 回答
3
  1. 确实如此,但这种方法并非没有优势。例如,在 POCO 和业务逻辑之间强制分离可以允许该逻辑被解耦并通过依赖注入或其他方式提供。
  2. 请记住,部分类不能跨越多个程序集(来自MSDN):

    所有属于同一类型的部分类型定义必须在同一程序集和同一模块(.exe 或 .dll 文件)中定义。部分定义不能跨越多个模块。

    尽管您可以改为使用扩展方法来实现所需的行为,但这种限制可能是不可取的。

  3. 我没有使用过 Automapper,所以 Ryan 的建议在这里适用。

  4. & 5. 我将这些组合在一起,因为使用 Code-First 会影响您的特定存储库实现。如果您还没有尝试过 Code-First,我建议您看看它。

在存储库方面,我更喜欢存储库在我们正在处理的 POCO 类型和可用操作方面完全通用。例如,使用 LINQ,存储库可以具有Get基于IEnumerable<T>给定Expression<Func<T, bool>>.

我喜欢这种方法,因为它允许对存储库进行依赖注入,将标准 CRUD 操作与更多特定于域的操作完全分开,同时为消费者/派生类的代码重用提供了很好的机会。

于 2012-12-18T08:38:51.130 回答
3

设计书籍、模式书籍和著名博主都可以,但是我们开发人员倾向于认为我们必须按照他们的建议开发我们的项目,即使这些书籍/文章没有为我们提供足够的上下文来理解它们适用于哪些情况以及它们何时适用不。

对于所有类型的应用程序都没有像好的设计这样的东西。我看到您专注于技术点,这没关系,但首先您应该回答最重要的问题:您的要求是否适合该设计?

请记住,您有需求、约束、资源和时间以及其他考虑因素,这迫使您参与必须指导您的设计的一些权衡。

例如:

  • 你真的需要存储库吗?您直接使用 EF 获得的实体是什么?
  • 你需要 DataModels 和 BizModels 吗?如果您只使用 TransactionScripts 会怎样?
  • 你需要UoW吗?为什么?EF 不能很好地为您处理这个问题吗?

这些问题的答案不是绝对的,它们取决于您的要求、时间、预算等。

现在,让我告诉你我对你的问题的看法:

  1. 的,由于某些原因,它闻起来很糟糕:a)POCO 对象应该是,嗯... POCO,这是因为您有 biz-object ,当然,它有逻辑但是...... POCO 对象有什么样的逻辑?
  2. 的,应该使用部分类而不是您的 xyzService。这更清楚,因为您的 xysServices 根本不是服务!
  3. 的,Automapper 可以处理映射问题。但是,它并不能解决您可能有很多映射的问题。同样,如果您不需要它,请避免使用它们。
  4. 您(或您的公司)是否有足够的金钱和时间来做到这一点?如今,没有人在没有绝对充分理由的情况下避免使用 ORM。所以,不,不要这样做!
  5. 同上 4。

这是我的意见。

于 2012-12-23T03:24:39.990 回答
2

您可能想走“代码优先”的道路。我曾经使用带有部分类的 EF 建模工具,但仍然存在重大问题,例如对生成的代码缺乏控制 - 更不用说建模器的零星问题,需要我重新创建关系。

使用“代码优先”,您可以更好地控制您的 POCO,以及许多额外的好处,例如数据库迁移,以及使用 T4 模板等以您喜欢的方式构建 POCO 的能力。

我不会回到 LinqToSQL,EF 功能更丰富,未来更光明,IMO。EF 现在是开源的,我查看了一些源代码以帮助解决我遇到的某些问题。

于 2012-12-22T13:51:35.250 回答