实体框架Core 1.0工作单元与Asp.Net Core中间件或Mvc过滤器
|
我正在使用EF Core 1.0(以前称为ad EF7)和ASP.NET Core 1.0(以前称为ASP.NET 5)的RESTful API. 我希望有一个单位的工作范围到一个http请求,在响应HTTP请求时,对DbContext所做的所有更改都将保存到数据库中,否则将保存(如果有的话)一些例外,例如). 在过去我已经使用WebAPI2与NHibernate通过使用一个Action过滤器,我开始执行操作的事务,并且执行的操作我结束事务并关闭会话.这是http://isbn.directory/book/9781484201107推荐的方式 不过现在我正在使用Asp.Net Core(Asp.Net Core Mvc,尽管这不应该是相关的),而我理解的实体框架已经实现了一个工作单元. 我认为有一个中间件插入到ASP.NET管道(在MVC之前)将是正确的办法.所以请求会去: PIPELINE ASP.NET:MyUnitOfWorkMiddleware ==> MVC控制器==>存储库==> MVC控制器==> MyUnitOfWorkMiddleware 我正在考虑如果没有异常发生,这个中间件保存DbContext的更改,所以在我的存储库实现中,我甚至不需要做dbcontext.SaveChanges(),而且一切都像一个集中式的事务.在伪码中,我猜想会是这样的: class MyUnitOfWorkMiddleware
{
//..
1-get an instance of DbContext for this request.
try {
2-await the next item in the pipeline.
3-dbContext.SaveChanges();
}
catch (Exception e) {
2.1-rollback changes (simply by ignoring context)
2.2-return an http error response
}
}
这是否有意义?有人有什么类似的事情吗?我没有找到任何良好的做法或建议. 此外,如果我在我的MVC控制器级别使用这种方法,在POST新的资源时,将无法访问数据库创建的任何资源ID,因为在保存dbContext更改之前不会生成该ID(稍后在管道中)在控制器完成执行后的中间件中).如果我需要访问控制器中新创建的资源ID,该怎么办? 任何建议将不胜感激! 更新1:我发现使用中间件来实现这一点的问题,因为中间件中的DbContext实例与MVC(和存储库)生命周期中的实例不同.见问题Entity Framework Core 1.0 DbContext not scoped to http request 更新2:我还没有找到一个很好的解决方案.基本上这些是我的选择: >尽快保存数据库中的更改.这意味着将其保存在存储库实现本身.这种方法的问题是,对于Http请求,也许我想使用几个存储库(即:将数据保存在数据库中,然后将BLOB上传到云存储),为了拥有工作单位,我必须实现一个处理多个实体或甚至多个持久性方法(DB和Blob存储)的存储库,其破坏了整个目的 return CreatedAtRoute(“GetCarById”,new {carId = carSummaryCreated.Id},carSummaryCreated); //carSummaryCreated.Id将为0,直到更改保存在DB中 我如何将整个控制器的操作包装在一个DB事务中,同时可以使用数据库生成的任何Id,以便从控制器返回Http响应?或者..有没有任何优雅的方式来覆盖http响应,并在数据库更改被提交后将动作过滤器级设置为Id? 更新3:根据nathanaldensr的评论,我可以通过使用代码生成Guids来获得两个世界中最好的(将控制器的操作执行包装在DB事务_ UoW中,并且知道即将在数据库提交更改之前创建的新资源的Id)依靠数据库生成Guid. 解决方法我也面临同样的问题,不知道应该遵循哪种方法.我使用的方法之一是: public class UnitOfWorkFilter : ActionFilterAttribute
{
private readonly AppDbContext _dbContext;
public UnitOfWorkFilter(AppDbContext dbContext,)
{
_dbContext = dbContext;
}
public override void OnActionExecuted(ActionExecutedContext context)
{
if (!context.HttpContext.Request.Method.Equals("Post",StringComparison.OrdinalIgnoreCase))
return;
if (context.Exception == null && context.ModelState.IsValid)
{
_dbContext.Database.CommitTransaction();
}
else
{
_dbContext.Database.RollbackTransaction();
}
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.HttpContext.Request.Method.Equals("Post",StringComparison.OrdinalIgnoreCase))
return;
_dbContext.Database.BeginTransaction();
}} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 认识ASP.NET配置文件Web.config
- IIS如何处理ASP.net MVC请求?
- asp.net – 如何重命名Visual Studio 2012中的IIS Express网
- 如何使用asp.net 5项目运行nunit测试,特别是使用ReSharper?
- 使用ASP.NET AJAX Control Toolkit设置焦点
- asp.net-mvc – 在ASP.NET MVC中的ReturnUrl
- asp.net-mvc – 使用@ Html.Partial渲染usercontrol(cshtml
- asp.net-mvc – 在REST Web API调用中返回复杂对象
- asp.net-mvc – 单元测试ASP.NET MVC中的自定义模型绑定2
- VS 2015.为ASP.NET 5 web项目设置正确的目标框架
- asp.net中的会话,缓存和配置文件有什么区别
- asp.net – asp:UpdateProgress – 保留换行符
- asp.net-mvc-4 – 将ninject dependecyResolver用
- 在ASP.NET中构建动态“高级搜索”控件的建议
- 我应该如何组织我的ASP.Net主题和常见的CSS文件
- asp.net – 如何在Firefox上命名文件以供下载?
- asp-classic – 如何在asp经典中触发异步调用并忽
- asp.net-mvc – ASP.NET MVC将表单值传递给actio
- asp.net-mvc – 在ASP.NET MVC中以HTML格式呈现R
- asp.net – 如何从URL抓取.aspx页面名称?
