【发布时间】:2014-03-25 17:51:23
【问题描述】:
我正在重新检查generic unit of work and repository framework 的实现。
我正在使用 EF6 和 VS2013。因此,VS 包含 WebAPI 控制器模板,这些模板使用如下实体框架代码自动生成带有操作的 WebAPI 2 OData 控制器:
// GET odata/UserProjects(5)/WebsiteRequiredKeywords
[Queryable]
public IQueryable<WebsiteRequiredKeyword> GetWebsiteRequiredKeywords([FromODataUri] int key)
{
return _db.Websites.Where(m => m.WebsiteId == key).SelectMany(m => m.WebsiteRequiredKeywords);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_db.Dispose();
}
base.Dispose(disposing);
}
private bool WebsiteExists(int key)
{ . . .
查看CustomerController class in the sample code - VS2013 模板中自动生成的代码看起来非常熟悉。如果我使用的是通用框架,我将不得不重构自动生成的代码以使用通用存储库语法、修改构造函数等。虽然我确信有一种方法可以修改模板生成过程以符合到这个通用存储库(或将我们自己的模板添加到 VS 模板中)- 这么多的工作似乎是不必要的。
通用脚手架模板使用相同的数据库上下文。据我了解,这是工作单元模式的同义词。
我现在正试图找到必须执行任何这些额外工作的价值。虽然我在以前的项目中成功使用了通用存储库和工作单元模式,但对于新项目,它是否只是比它的价值更多(因为存在一些概念重复 b/t EF 和这种模式也是如此)?
-- 更新--
对自动生成的代码做了一些小的修改,在实现这样的东西之后我需要做什么:
public class ProjectEditorController : ODataController
{
//private MyDatabaseNameContext db = new MyDatabaseNameContext(); // auto-generated code
private DbContext _db;
public ProjectEditorController(DbContext dbContext)
{
_db = dbContext;
}
. . .
这段代码的问题是现在没有具体的上下文,并且做的事情如下:
return SingleResult.Create(_db.Websites.Where(website => website.WebsiteId == key));
...不起作用,因为db 和实体之间没有具体的联系,即。 Websites.
在使用DI for WebAPI Controllers 时,您仍然需要定义一个存储库。如果我想注入 dbContext 我需要使用通用回购,这是一种情况吗?
简而言之,这是否准确:如果您想有效地使用依赖注入,那么您需要一个通用存储库。否则,您需要为所有 EF 实体定义存储库接口,除非您使用 IDependency 解析器,如 this 文章末尾所建议的那样。
【问题讨论】:
-
这些新模板是否共享相同的数据上下文?因为,如果他们不共享数据上下文是 UOW 模式的关键部分,那么它就不是一个等效的比较。还是这样?
-
是否有值得进行所有重构的理由?如果没有那么放松。过度设计很容易,并且您可以在以后有需要时进行重构。如果值得,请安装MVC 5 Code Templates,如果您要继续这样做,可以节省一些时间。
-
@BigDaddy - 我使用新的构造函数更新了默认代码,您可以在其中定义上下文。查看更新后的问题。
-
在过去的几年里,当我们没有像 EF 这样的抽象时,存储库很有意义。使用图片中的 EF,我发现实现存储库可能需要做很多额外的工作,但收益很少(或没有收益)。所以我倾向于做(除非有充分的理由不这样做)是创建 IQuerable
的扩展方法并以这种方式组织我的代码。 2p -
@ElHaix...看起来您可以使用 DI 容器来注入您的上下文。
标签: c# generics entity-framework-6 generic-collections