实体框架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-mvc – ASP.NET MVC自定义路由约束和依赖注入
- asp.net-mvc – UpdateModel和TryUpdateModel
- asp.net – 代码无效或已过期.使用API??调用显式使会话无效
- asp.net – 如何删除特定页面中的cookie?
- asp.net – 如何使用Docx dll生成word文档时在标题中添加图
- 具有多个身份验证过滤器的ASP.net Web API 2控制器
- asp.net – GridView’GridView1’触发的事件PageIndexChan
- asp.net-mvc – 如何在MVC中调用.ashx文件?
- asp.net – Firefox 4.0总是刷新Silverlight XAP文件
- asp.net-mvc – 在ASP MVC中,如何将新视图和文件返回给用户
- asp.net – Session_Start没有解雇
- asp.net-mvc – 用于json嵌套数组的MVC3绑定
- asp.net-mvc – Mac上是否有一个好的编辑器支持A
- asp.net-mvc – Orchard CMS中的SignalR聊天模块
- asp.net-mvc – ASP.Net MVC添加控制器错误
- 如何获取ASP.NET应用程序的完整虚拟路径
- asp.net-mvc – 缩小ASP.NET MVC中的Action Filt
- asp.net-mvc – ASP MVC:为什么我的视图中看不到
- asp.net-core – 如何将值更新到appsetting.json
- asp.net – Visual Studio加载项自动附加到Devel