2017-07-30 53 views
0

我想確保處理我的EF dbContext對象。在MVC控制器中處理EF DBContext

目前我正在使用靜態方法來調用EF crud操作,以保持所有數據層的東西黑色框和控制器。

下面的例子我有一個方法返回一個IQueryable,並使用一個使用語句,當查詢試圖在一個處置的上下文對象上運行時導致異常。

另一個不使用Using語句,工作正常,但是它被丟棄?

我應該只是返回IEnumerable而不是IQueryable?

public class MyContext : DbContext 
{ 
    public MyContext() : base("MyConnectionString") 
    { 
     Database.SetInitializer<EFContext>(null); 
    } 

    public DbSet<User> Users { get; set; } 
    public DbSet<Role> Roles { get; set; } 
} 


public class Data 
{ 
    // Fails when IQuerable tried to run against a disposed MyContext object 
    public static T Get<T>(params string[] joins) 
    { 
     using (var context = new MyContext()) 
     { 
      return context.Get<T>(joins); 
     } 
    } 

    // Works fine but when is it disposed? 
    public static T Get<T>(params string[] joins) 
    { 
     return new MyContext().Get<T>(joins); 
    } 
} 

public ActionResult GetUser(int id = 0) 
{ 
    var data = Data.Get<User>(); 
    return View("Users", model); 
} 

回答

4

的問題不在於使用IQueryableIEnumerable。你有例外,因爲通過返回IQueryableIEnumerable,你沒有執行LINQ。您只需打開一個到數據庫的連接,然後在配置完查詢後關閉。

要解決此問題,您需要通過調用ToListToArray,Single[OrDefault],First[OrDefault] etc ...擴展方法來執行LINQ查詢。

因爲您正在使用Web應用程序,所以在您的Web請求的整個生命週期中,有一個DbContext的實例是最佳實踐。我建議你使用DI(依賴注入),它會幫助你很多。你可以試試Simple Injector這是非常簡單的DI。

如果你不能夠使用DI所以只要按照這個步驟,但需要時間來了解DI請:):

  1. 當Web請求到達時,你DbContext的新實例存儲到HttpContext.Items集合。
  2. 在你的方法中,只需從HttpContext.Items中檢索存儲的DbContext並使用它。
  3. 當Web請求正在終止時,只需處理DbContext即可。
+0

我對DI很熟悉,但正如我在OP中所說的,我想保留任何數據訪問的東西離開我的UI層和黑盒子。幾乎就像使用它一樣API – user3953989

+2

DI幫助你做到這一點。您將遵循所有SOLID原則,其中包括您嘗試執行的黑盒子操作,因爲您將再次編程接口/抽象。 – CodeNotFound

+0

你可以添加一個這樣的例子嗎? – user3953989

相關問題