我有一个使用实体图案的visual studio解决方案。我有一个IRepository(Crud实现),IDbFactory(由存储库使用),IUnitOfWork。我也有服务,他们使用存储库来构建自定义查询和复杂的数据库操作。我正在使用Ninject的IoC模式。 在web mvc控制器中,我只使用服务来访问数据库。 存储库接收构建EntityFramework Context的IDbFactory。 我有一些问题:
我的项目结构有问题吗?这是我必须在存储库层中修复的东西?我该怎么办?该项目正处于开发阶段,因此我可以更改数据访问架构。我喜欢在控制器中使用IQueryables,因此数据网格中的用户过滤器会生成sql查询。
答案 0 :(得分:4)
那么,就你所说的问题而言,你的项目结构没有任何问题。问题源于使用Singleton范围。相反,您应该将Web范围用于Web应用程序。这可确保您获得每个请求的新上下文,因此不同请求之间甚至不同客户端之间不会重叠,这可能非常危险。
也就是说,您的项目结构过度设计。存储库/工作模式单元用于低级数据访问。 ORM与Entity Framework一样,处理所有这些,实际上,Entity Framework已经实现了这些模式。 DbContext
是工作单元,每个DbSet
都是一个存储库。在此基础上添加您自己的存储库/工作单元层是多余且不必要的。您的服务应直接使用您的Entity Framework上下文。即使这样,也可能不需要拥有多项服务,这取决于他们的工作。如果它们都使用相同的数据源(即实体框架上下文),特别是如果它们都与相同的实体框架上下文一起使用,那么它们应该全部归为一个。
在我自己的个人项目中,我使用单个“服务”类,每个唯一的上下文实例使用泛型方法。通用方法允许我使用属于该上下文的任何实体,而无需新建“服务”类的其他实例。通过确保一切实现一个或多个接口并使用依赖注入来满足接口约束,底层数据层完全被排除在外。我有一个series of posts如果你有兴趣可以更详细。
我说这一切都是因为你似乎过分关注模式和“最佳实践”。这些只是指南。他们就像在自行车上训练轮子。它们都基于良好代码设计的各种原则。学习并应用原则,不要担心检查某种设计模式列表中的所有框。
有趣的是,Stack Overflow的核心代码库实际上避开了许多模式(甚至是依赖注入),因为它们专注于原始性能,而某些设计模式在应用时实际上会阻碍性能。关键是应用程序的设计方式应该基于特定应用程序的需求。设计模式应该只应用于与应用程序需求一致的程度,而不仅仅是因为您认为自己应该这样做。
答案 1 :(得分:0)
首先,DbContext的生命周期应该持续整个业务部门,在MVC应用程序中,这是每个HttpRequest。它从发送请求开始提供事务,以便用户接收响应。
其次,您不应该在基础存储库中拥有GetAll()
函数。这是非常错误的解决方案,它可能会影响应用程序的性能。您应该创建如下函数:GetByQuery(Func<T, bool> whereQuery, int skip, int take)
其中T是实体类的泛型类型。或者,您可以添加用于排序的参数。
也许您应该考虑存储库模式的辞职?你的项目有多大?是否有可能在未来改变数据存储?如果没有,您可以直接在服务中的DbContext上操作。实体框架是存储库模式和UnitOfWork的一种实现。