上篇中"Entity Framework中的Identity map和Unit of Work模式", 因爲EF中的Identity map和Unit of Work模式,EF體現出來以下特性:html
惟一性: 在一個Context的生命週期中,一個Entity只會有一個實例,任何對該實例的修改,即便這些改動沒有保存到數據庫中,修改都會影響到整個Context的生命週期。數據庫
事務性: 全部對於Entity的修改,都會在調用SaveChange方法的時候,一塊兒保存到數據庫中,最終實現持久化。緩存
下面基於EF的上面特色,分析一下爲何須要在MVC中實現One Context Per Request, 也就是在一個Request生命週期中,只有一個Context.函數
閱讀目錄:性能
1、每次建立Context的缺點ui
2、使用全局Context的缺點spa
3、在MVC中實現One Context Per Request.net
4、藉助Autofac實現One Context Per Requestcode
通常在項目的數據訪問層中使用Entity Framework,代碼以下orm
public IEnumerable<Student> GetStudents() { using (var context = new SchoolContext()) { return context.Students.ToList(); } }
這個是數據訪問層中很是常見的方法,返回DB中全部的Student數據。
這裏在使用Context的時候,建立一個Context的實例進行操做。
可是這種方式帶來了下面一些缺點:
看到了"每次建立Context」的缺點,可能會認爲使用全局Context是個好的解決方案。
可是全局Context帶來的問題更大:
因此:
思路是這樣的, 在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是.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容器提供