2012-08-26 30 views
2

我最近一直在使用Entity Framework 4.3和Dependancy Injection學習MVC3,所以我可以在以後實現單元測試。我現在試圖實現我在各種示例中看到的一些功能,但是我遇到了一些似乎源於我使用依賴注入的問題,因此我希望有人指出我出錯的地方。MVC3使用EF4.3和Dependancy Injection問題

我的第一個問題很簡單,在我看到的大多數MVC3示例中,訪問數據庫是在控制器中完成的,但是在使用依賴注入時,我似乎需要將此代碼重構爲實現的存儲庫。這是正常的和正確的?

我的第二個更深入的問題是處理這個簡單的例子:

我在我的倉庫類了這種方法,幾乎​​從在線例子(here)複製。但是,我收到有關Include部分的錯誤,並且intellisense確實說這個變量需要是一個字符串。我已經嘗試了前面提到的鏈接的原始代碼,並且工作正常,該項目之間唯一的主要區別是我正在使用依賴注入。

public ExampleUser GetStruContractUser(int id) 
{ 
    ExampleUser user = context.ExampleUsers 
     .Include(i => i.ExampleRoles) 
     .Where(i => i.UserID == id) 
     .Single(); 

    return user; 
} 

Include參數更改爲以下工作正常。

public ExampleUser GetStruContractUser(int id) 
{ 
    ExampleUser user = context.ExampleUsers 
     .Include("ExampleRoles") 
     .Where(i => i.UserID == id) 
     .Single(); 

    return user; 
} 

僅供參考這是我用我的DbContext類:

public class EFDbContext : DbContext 
{ 
    public DbSet<ExampleUser> ExampleUsers { get; set; } 
    public DbSet<ExampleRole> ExampleRoles { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     modelBuilder.Entity<ExampleUser>().ToTable("User", "MySchema"); 
     modelBuilder.Entity<ExampleRole>().ToTable("Role", "MySchema"); 

     modelBuilder.Entity<ExampleUser>() 
      .HasMany(m => m.ExampleRoles) 
      .WithMany(t => t.ExampleUsers) 
      .Map(a => 
      { 
       a.MapLeftKey("UserID"); // your PK column name in user table 
       a.MapRightKey("RoleID"); // your PK column name in role table 
       a.ToTable("UserRole", "MySchema"); // your join table name 
      }); 
     } 
    } 

這是一個問題,由於我使用扶養注射的或者是有別的事情上,我誤會?

如果您需要更多信息,請詢問我將盡力提供。

非常感謝。

回答

1

是,提取數據庫層(資料庫/上下文),然後將其注入到業務層(控制器)是非常正常的,一個很好的方式面向未來的應用程序。如果你曾經想將實體框架中的數據庫ORM更改爲其他內容呢?與您的控制器緊密結合會產生巨大的麻煩。

你的第二個問題,有include,是毫無關係的扶養注射。

Include on dbset使用lambda作爲System.Data.Entity的擴展名。如果你想使用它,你需要包含該參考。

2

問題1: 使用DI不會強制您使用存儲庫模式,實際上它們並不相關。這只是避免將控制器類緊密耦合到數據庫上下文類,並能夠更輕鬆地測試這些類的好方法。存儲庫使您能夠隱藏如何訪問數據庫的實現細節,並允許您切換ORM:s,如果發生這種情況(它永遠不會發生)。版本庫依賴於爲您的DbContext提供接口,使用DI也是如此。

你想要做的是通過接口使用你的數據庫,並且當你使用DI時,你可以在控制器的構造函數中注入對DbContext類的引用,並讓DI控制器執行爲你工作。

之所以將定義存儲庫的接口傳遞給Controller來傳遞定義DbContext的接口,是因爲使後者的接口容易變得過於複雜,而堅持存儲庫是因爲簡單得多。爲了簡單起見,我首先直接使用DbContext,然後從那裏擴展。

問題2:

包括需要包含表作爲一個字符串的名稱。所以你後面使用Include是正確的,前者不是。

如果我沒記錯的話,你可以這樣做壽: 「.INCLUDE(I => i.ExampleRoles.Name)」 來實現同樣的事情。