2012-03-19 62 views
0

爲了支持EF中的延遲加載功能,實例化DbContext的最佳方法是什麼?什麼是爲ASP.NET MVC創建EF DbContext實例的最佳方法

我知道HttpContext目前的產品通過Application_BeginRequest方法和Application_EndRequest方法來創建DbContext好地方,但在MSDN和官方asp.net的MVC網站的一些示例代碼,他們只是在控制器的構造函數創建DbContext和處置它控制器的Dispose()方法。

我認爲這兩種方式都不是太不同,因爲所有這些都實現會話每請求模式。

我只是想確保我的理解是否正確。

回答

1

控制器中的Dispose()方法並不總是可靠的。同樣,Session也可能不是一個好主意。 「最佳」可能是主觀的,但通過使用依賴注入(Castle Windsor)和遵循工作單元庫模式,我們取得了最好的成功。

安裝工作的單位大致如下:

public class UnitOfWork : IUnitOfWork 
{ 
    public UnitOfWork() 
    { 
     this.Context = new MyEFEntities(); 
     this.Context.ContextOptions.LazyLoadingEnabled = true; 
    } 

    public void Dispose() 
    { 
     this.Context.Dispose(); 
    } 

    public ObjectContext Context { get; internal set; } 
} 

設置你的資料庫:在Global.asax中與城堡

public class Repository<TEntity> : IRepository<TEntity> 
    where TEntity : class 
{ 
    public Repository(IUnitOfWork unitOfWork) 
    { 
     Context = unitOfWork.Context; 
     ObjectSet = Context.CreateObjectSet<TEntity>(); 
    } 
    public ObjectContext Context { get; set; } 
    public IObjectSet<TEntity> ObjectSet { get; set; } 
} 

註冊:

void Application_Start() 
{ 
    this.Container.Register(
     Component.For<IUnitOfWork>() 
      .UsingFactoryMethod(() => new UnitOfWork()) 
      .LifeStyle 
      .Is(LifestyleType.PerWebRequest) 
     ); 

    ControllerBuilder.Current.SetControllerFactory(
     new WindsorControllerFactory(this.Container)); 
} 

和使用您的控制器(或您使用它的任何地方,只要它是可注射的):

public class SomeController 
{ 
    public SomeController(IRepository<MyEntity> repository) 
    { 
     this.Repository = repository; 
    } 

    public IRepository<MyEntity> Repository { get; set; } 

    public ActionResult MyAction() 
    { 
     ViewData.Model = this.Repository.ObjectSet.Single(x => x.Condition); //or something... 
    } 
} 
+0

感謝您的回覆lukiffer,但我的問題集中在更基礎的東西不存儲庫,而不是DI的東西。我只是想知道什麼方法在begin/endrequest事件或控制器類中最好,而不使用存儲庫和DI容器。 – Ray 2012-03-19 05:40:07

+0

通過附加到開始/結束請求事件,您可以在請求的整個生命週期中訪問相同的datacontext實例,而不僅僅是在控制器中(例如過濾器等),但最終它們是相同的。我提出長篇解釋的唯一原因是因爲我在網上農場/網絡花園的請求上下文中遇到了問題,最終這是唯一有效的工作。 – lukiffer 2012-03-19 05:46:07

+0

你的意思是這兩種方式都可以支持延遲加載,對吧? – Ray 2012-03-19 15:13:01

1

這裏的任何延遲加載都有可能成爲未來問題的陷阱。沒有DI,沒有存儲庫 - 很難看到任何工作,沒有對延遲加載的破解。你也打算將你的實體傳遞給你的觀點。如果是這樣,這將造成重疊不良。控制器應爲您的視圖打包數據,而不是在您的視圖中稍後評估。

對於MVC最佳實踐,您應儘可能將視域模型平鋪到視圖模型中(如果拼合有意義)並使用視圖模型。既然你理想的情況下知道什麼會被延遲加載,那麼將前面的命中並在查詢中使用.Include()來加載負載可能更有意義,否則可以向數據庫發出很多查詢。

0

我已經使用會話工廠模式並將DBContext保存在會話對象中。它將保持每個會話的開放。到目前爲止,我沒有遇到任何問題。

相關問題