Entity Framework在Asp.net MVC中的实现One Context Per Request(附源码)

简介:

上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现出来如下特性:

唯一性: 在一个Context的生命周期中,一个Entity只会有一个实例,任何对该实例的修改,即使这些改动没有保存到数据库中,修改都会影响到整个Context的生命周期。

事务性: 所有对于Entity的修改,都会在调用SaveChange方法的时候,一起保存到数据库中,最终实现持久化。

下面基于EF的上面特点,分析一下为什么需要在MVC中实现One Context Per Request, 也就是在一个Request生命周期中,只有一个Context.

阅读目录:

一、每次创建Context的缺点

二、使用全局Context的缺点

三、在MVC中实现One Context Per Request

四、借助Autofac实现One Context Per Request

一,每次创建Context的缺点

一般在项目的数据访问层中使用Entity Framework,代码如下

复制代码
public IEnumerable<Student> GetStudents()
{ 
       using (var context = new SchoolContext()) 
       { 
           return context.Students.ToList(); 
       } 
}
复制代码

这个是数据访问层中非常常见的方法,返回DB中所有的Student数据。

这里在使用Context的时候,创建一个Context的实例进行操作。

但是这种方式带来了下面一些缺点:

  • 首先,每次的数据处理,都用new context, 会导致更多的资源开销。
  • 假如业务逻辑层调用GetStudents方法获取到数据之后,要访问Student的导航属性School怎么办? 逻辑层代码使用导航时候就会导致异常,因为EF只能在context生命周期中,才能够再次请求数据库,取得导航属性School的数据。
  • 如果是插入操作,而且是多个关联表的数据插入,插入操作在不同的context中完成,就无法应用EF的事务效果。保证数据能够同时插入成功,如果失败,就一起回滚。
  • 如果在循环中插入数据,每次插入数据都是在不同的context中完成,性能就是一个悲剧。

二,使用全局Context的缺点

看到了"每次创建Context”的缺点,可能会认为使用全局Context是个好的解决方案。

但是全局Context带来的问题更大:

  • 如果全局使用一个Context,会导致越来越多的数据缓存到本地, 随着程序的使用时间越长,占用的资源越来越大。
  • 使用全局Context, 会导致缓存数据无法得到及时更新。即使数据库中的数据有改动,使用EF取出来得数据有可能还是改动之前的数据。

所以:

  • 在MVC项目中,建议每个request, 使用一个Context
  • 在Winform中和WPF中,一个Form或者一个Presenter一个Context
  • 在WebService, Web API中,每次调用, 使用一个Context.

三, 在MVC中实现One Context Per Request

思路是这样的,  在Global.asax.cs文件中,在Begin Request事件中,创建和保存Context; 在End Request事件中,销毁Context. 另外提供一个公开的静态属性来获取这个Context。

详细的代码如下:

在Global.asax.cs中

复制代码
protected virtual void Application_BeginRequest()
{
    HttpContext.Current.Items["_EntityContext"] = new EntityContext();
}

protected virtual void Application_EndRequest()
{
    var entityContext = HttpContext.Current.Items["_EntityContext"] as EntityContext;
    if (entityContext != null)
        entityContext.Dispose();
}
复制代码

添加静态属性,以便程序中能够方便的取出和使用Context

复制代码
public class EntityContext
{
    public static EntityContext Current
    {
        get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; }
    }
}
复制代码

四,借助Autofac实现One Context Per Request

Autofac是.net的Ioc容器,具体使用的方法,可以看这里 IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)

本文的Demo源码,是在上面博客附带的源码基础上修改而来的。

这里,只是介绍一下如何使用Autofac注册Context

在Application_Start函数体内,执行如下代码

复制代码
var builder = new ContainerBuilder(); //创建builder
//注册builder, 实现one context per request
builder.RegisterType<eassistdevContext>().InstancePerHttpRequest();

var container = builder.Build();//创建容器
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//覆盖MVC默认的实例化Controller的方法,转而又Auotfac容器提供 
复制代码

更详细的过程,可以在这里直接下载源代码 AutofactMVC(One-Context-Per-Request).zip

源代码中也使用了MiniProfler,推荐一下


本文转自JustRun博客园博客,原文链接:http://www.cnblogs.com/JustRun1983/p/3249462.html,如需转载请自行联系原作者


目录
相关文章
|
25天前
|
开发框架 .NET BI
ASP.NET公立医院健康体检信息管理系统源码
健康体检信息管理系统是专门针对医院体检中心的日常业务运作的特点和流程,结合数字化医院建设要求进行设计研发的一套应用系统。该系统覆盖体检中心的所有业务,完成从预约、登记、收费、检查、检验、出报告、分析、报表等所有工作,规范了体检流程,提高了工作效率。体检系统为每个体检者建立一套完整的体检档案,与病人的门诊、住院诊疗信息有机集成, 真正体现数字化医院以病人为中心的建设原则。
20 1
|
26天前
|
开发框架 安全 .NET
ASP.NET三甲医院手术麻醉信息管理系统源码 对接麻醉机、监护仪、血气分析仪
辅助医院建设 •支持三级医院评级需求 •支持智慧医院评级需求 •支持互联互通评级需求 •支持电子病历评级需求
21 0
|
3月前
|
开发框架 Oracle 关系型数据库
ASP.NET实验室LIS系统源码 Oracle数据库
LIS是HIS的一个组成部分,通过与HIS的无缝连接可以共享HIS中的信息资源,使检验科能与门诊部、住院部、财务科和临床科室等全院各部门之间协同工作。 
39 4
|
4月前
|
SQL 开发框架 .NET
分享53个ASP江湖论坛源码,总有一款适合您
分享53个ASP江湖论坛源码,总有一款适合您
|
4月前
|
开发框架 前端开发 JavaScript
盘点72个ASP.NET Core源码Net爱好者不容错过
盘点72个ASP.NET Core源码Net爱好者不容错过
72 0
|
8天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
18 0
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
2月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
2月前
|
开发框架 搜索推荐 .NET
ASP.NET体检中心源码,实现检前、检中、检后全流程管理
健康体检系统遵循整个健康体检的实际流程,以提高工作效率、降低错检、防止漏检提高人性化服务水平为目的,在体检过程中可以高效、自动化、人性化的处理数据与提供服务。针对体检流程中工作强度在时间分配上不均匀等特点,解决了体检信息处理效率问题,在不增加体检中心人力资源投入或少投入的基础上,提升信息处理的效率,从而突破体检中心日处理体检人数的上限,为体检中心创造更大经济效益的同时,还能有效的降低体检工作者的劳动强度。
36 5
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
101 5