我一直使用存储库模式,但对于我的最新项目,我想看看我是否可以完善它的使用以及我对“工作单元”的实现。我开始挖掘的越多,我开始问自己这个问题: “我真的需要吗?”
现在这一切都始于对 Stackoverflow 的几条评论,以及 Ayende Rahien 在他的博客上的帖子,其中有 2 个具体的,
这可能会永远被谈论,它取决于不同的应用程序。我想知道的,
使用扩展方法很容易做到这一点。干净、简单且可重复使用。
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/