entity-framework - 不使用存储库模式,按原样使用 ORM (EF)

标签 entity-framework design-patterns architecture aop repository-pattern

我一直使用存储库模式,但对于我的最新项目,我想看看我是否可以完善它的使用以及我对“工作单元”的实现。我开始挖掘的越多,我开始问自己这个问题: “我真的需要吗?”

现在这一切都始于对 Stackoverflow 的几条评论,以及 Ayende Rahien 在他的博客上的帖子,其中有 2 个具体的,

  • repository-is-the-new-singleton
  • ask-ayende-life-without-repositories-are-they-worth-living

  • 这可能会永远被谈论,它取决于不同的应用程序。我想知道的,
  • 这种方法是否适合 Entity Framework 项目?
  • 使用这种方法是业务逻辑仍在服务层中,还是扩展方法(如下所述,我知道,扩展方法是使用 NHib session )?

  • 使用扩展方法很容易做到这一点。干净、简单且可重复使用。
    public static IEnumerable GetAll(
        this ISession instance, Expression<Func<T, bool>> where) where T : class
    {
        return instance.QueryOver().Where(where).List();
    }
    

    使用这种方法和 Ninject作为 DI,我需要制作 Context一个接口(interface)并将其注入(inject)我的 Controller ?

    最佳答案

    我走了很多路,并在不同的项目上创建了许多存储库实现......我已经放弃并放弃了它,这就是原因。

    异常编码

    您是否为您的数据库从一种技术更改为另一种技术的 1% 机会编写代码?如果您正在考虑您的业务的 future 状态并说是的,那么 a)他们必须有很多钱来负担迁移到另一种数据库技术的费用,或者 b)您选择一种数据库技术是为了好玩或 c ) 您决定使用的第一种技术出现了严重错误。

    为什么要抛弃丰富的 LINQ 语法?

    开发了 LINQ 和 EF,因此您可以用它做一些简洁的事情来读取和遍历对象图。创建和维护一个可以为您提供同样灵 active 的存储库是一项艰巨的任务。以我的经验,任何时候我创建了一个存储库,我都有 总是 业务逻辑泄漏到存储库层,以提高查询的性能和/或减少对数据库的访问次数。

    我不想为我必须编写的查询的每一个排列创建一个方法。我还不如写存储过程。我不要 GetOrder , GetOrderWithOrderItem , GetOrderWithOrderItemWithOrderActivity , GetOrderByUserId ,依此类推...我只想获取主要实体并随意遍历并包含对象图。

    大多数存储库示例都是胡说八道

    除非您正在开发像博客这样的非常简单的东西,否则您的查询永远不会像您在 Internet 上找到的围绕存储库模式的示例中的 90% 那样简单。我不能强调这一点!这是一个人必须在泥泞中爬行才能弄清楚的事情。总会有一个查询会破坏您创建的经过深思熟虑的存储库/解决方案,直到您再次猜测自己并开始技术债务/侵 eclipse 的那一刻。

    不要对我进行单元测试兄弟

    但是如果我没有存储库,那么单元测试呢?我将如何 mock ?很简单,你不会。让我们从两个角度来看它:

    没有存储库 - 您可以模拟 DbContext使用 IDbContext或其他一些技巧,但是您实际上是在对 LINQ to Objects 而不是 LINQ to Entities 进行单元测试,因为查询是在运行时确定的……好吧,那不好!所以现在由集成测试来解决这个问题。

    使用存储库 - 您现在可以模拟您的存储库并对中间的层进行单元测试。很棒吧?不是真的......在上述情况下,您必须将逻辑泄漏到存储库层以提高查询的性能和/或减少对数据库的访问,您的单元测试如何涵盖这一点?它现在在 repo 层,你不想测试 IQueryable<T>对?老实说,您的单元测试不会涵盖具有 20 行 .Where() 的查询。子句和 .Include()是一堆关系并再次访问数据库以执行所有其他操作,等等等等,因为查询是在运行时生成的。此外,由于您创建了一个存储库以保持对上层持久性的无知,如果您现在想要更改数据库技术,很抱歉您的单元测试绝对不能保证在运行时获得相同的结果,回到集成测试。所以存储库的整个点似乎很奇怪..

    2 美分

    在普通存储过程(批量插入、批量删除、CTE 等)上使用 EF 时,我们已经失去了很多功能和语法,但我也在 C# 中编写代码,因此我不必键入二进制文件。我们使用 EF,因此我们可以使用不同的提供者,并以一种很好的相关方式处理对象图。某些抽象是有用的,而有些则不是。

    关于entity-framework - 不使用存储库模式,按原样使用 ORM (EF),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14110890/

    相关文章:

    java - 为什么另一个分支在我的代码中无法访问?

    mysql - 配置数据 - JSON 存储在表中与单个字段中

    web-services - 分布式服务如何比分布式对象更好?

    c# - 使用 EF 从 Azure 移动服务检索父/子记录(包含列表的对象)

    entity-framework - EntityFramework 4、DbSet 和 ObjectContext

    java - 为什么即使实现了 Iterable,我也会收到 foreach 编译器错误?

    architecture - "Phones Home"的软件;好的?坏的?邪恶?发出什么通知?如何?

    c# - Entity Framework DataContext 问题 - 它是否在我的 Controller 中得到正确处理?

    c# - MigrationHistory 作为 Entity Framework 7 中 DbContext 中的实体

    c# - 工厂类还包括从数据库中提取数据的功能是否合适