3

我正在使用實體框架7並創建了兩個項目。一個項目作爲ASP.NET 5 Web API項目,另一個項目是一個類庫項目(包),我希望將所有數據訪問層邏輯存儲在其中。這樣,我可以將此包用於另一個報告項目我可能提供的其他附加服務。如何在類庫項目中正確定義DBContext?

基本上,我在我的數據庫項目中調用函數的web api項目控制器中有一個簡單的帖子。當函數啓動數據庫時,它說數據庫沒有定義,甚至在兩個項目中都定義了它。


錯誤

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."} 

CODE

數據圖書館項目:InsertPerson

public int InsertPerson(tbl_Person person) 
{ 
    using (var db = new AppContext()) 
    { 
     try 
     { 
      db.tbl_Person.Add(person); 
      db.SaveChanges(); 
      return person.PersonID; 
     } 

     catch 
     { 
      return 0; 
     } 
    } 
} 

器配置文件

的Web API項目:Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddEntityFramework() 
     .AddSqlServer() 
     .AddDbContext<AppContext>(options => 
      options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); 

    services.AddIdentity<ApplicationUser, IdentityRole>() 
     .AddEntityFrameworkStores<AppContext>(); 

    services.AddMvc(); 
} 

的Web API項目:appsettings.json

{ 
    "Data": { 
    "DefaultConnection": { 
     "ConnectionString": "Server=localhost;Database=testDB;Trusted_Connection=True;MultipleActiveResultSets=true" 
    } 
    }, 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Verbose", 
     "System": "Information", 
     "Microsoft": "Information" 
    } 
    } 
} 

的Web API項目:project.json

{ 
    "userSecretsId": "blah, 
    "version": "1.0.0-rc1-final", 
    "compilationOptions": { 
    "emitEntryPoint": true 
    }, 

    "dependencies": { 
    "DataLibrary": "", 
    "Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-beta7", 
    "Microsoft.AspNet.Http.Abstractions": "1.0.0-rc1-final", 
    "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final", 
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", 
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", 
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", 
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Logging": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", 
    "Remotion.Linq": "2.0.1" 
    }, 

    "commands": { 
    "web": "Microsoft.AspNet.Server.Kestrel" 
    }, 

    "frameworks": { 
    "dnx451": { }, 
    "dnxcore50": { } 
    }, 

    "exclude": [ 
    "wwwroot", 
    "node_modules" 
    ], 
    "publishExclude": [ 
    "**.user", 
    "**.vspscc" 
    ] 
} 

數據圖書館項目:Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddEntityFramework() 
     .AddSqlServer() 
     .AddDbContext<AppContext>(options => 
      options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); 

    services.AddIdentity<ApplicationUser, IdentityRole>() 
     .AddEntityFrameworkStores<AppContext>(); 

    services.AddMvc(); 
} 

數據圖書館項目:AppSettings的。 json

{ 
    "Data": { 
    "DefaultConnection": { 
     "ConnectionString": "Server=localhost;Database=testDB;Trusted_Connection=True;MultipleActiveResultSets=true" 
    } 
    }, 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Verbose", 
     "System": "Information", 
     "Microsoft": "Information" 
    } 
    } 
} 

數據圖書館項目:AppContext.cs

namespace DataLibrary 
{ 
    public class AppContext : IdentityDbContext<ApplicationUser> 
    { 
     public DbSet<tbl_Person> tbl_Person { get; set; } 

     public static AppContext Create() 
     { 
      return new AppContext(); 
     } 

     protected override void OnModelCreating(ModelBuilder builder) 
     { 
      new tbl_PersonMap(builder.Entity<tbl_Person>()); 
      base.OnModelCreating(builder); 
     } 
    } 
} 
+0

您是否嘗試將連接字符串存儲在App.Config中? –

+0

@VijayKumbhoje配置工作,否則數據庫wouldnt已經創建時,我在數據庫項目中運行dnx ef更新數據庫。從我目前看到的,我認爲我必須弄清楚如何將我的上下文設置從web api啓動注入到函數中。如果我只在數據庫中工作,那麼當它的web api項目是失敗的啓動項目時 – chris

+0

你見過這個教程嗎? http://www.jerriepelser.com/blog/moving-entity-framework-7-models-to-external-project –

回答

2

它看起來像在示例代碼您的問題是,你是newing了AppContext實例,而不是從解決的ServiceProvider它。當以這種方式初始化DbContext時,會爲該上下文隱式創建一個新的ServiceProvider,並且該上下文不會考慮Startup.cs中的任何配置。如果您在OnConfiguring中配置了上下文,並且對其他應用程序中的依賴注入不感興趣,則這是一種您希望使用的模式。

在這種情況下,我希望你通過構造函數注入來獲得AppContext。對於這種解決方案,您還需要在ServiceCollection中註冊您的數據訪問層類。結果應該多一點這樣的:

數據圖書館項目:AppContext.cs

namespace DataLibrary 
{ 
    public class AppContext : IdentityDbContext<ApplicationUser> 
    { 
     public DbSet<tbl_Person> tbl_Person { get; set; } 

     protected override void OnModelCreating(ModelBuilder builder) 
     { 
      new tbl_PersonMap(builder.Entity<tbl_Person>()); 
      base.OnModelCreating(builder); 
     } 
    } 
} 

數據圖書館項目:PersonH​​elper.cs

namespace DataLibrary 
{ 
    class PersonHelper 
    { 
     private readonly AppContext db; 

     public PersonHelper(AppContext context) 
     { 
      db = context; 
     } 

     public int InsertPerson(tbl_Person person) 
     { 
      try 
      { 
       db.tbl_Person.Add(person); 
       db.SaveChanges(); 
       return person.PersonID; 
      } 
      catch 
      { 
       return 0; 
      } 
     } 
    } 
} 

的Web API項目:Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddEntityFramework() 
     .AddSqlServer() 
     .AddDbContext<AppContext>(options => 
      options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); 

    services.AddIdentity<ApplicationUser, IdentityRole>() 
     .AddEntityFrameworkStores<AppContext>(); 

    services.AddScoped<PersonHelper>(); 

    services.AddMvc(); 
} 

的Web API項目:MyController.cs

[Route("api/[controller]")] 
public class MyController : Controller 
{ 
    private readonly personHelper helper; 

    public MyController(PersonHelper helper) 
    { 
     this.helper = helper; 
    } 

    // POST api/my 
    [HttpPost] 
    public void Post([FromBody]string value) 
    { 
     var person = new tbl_Person 
     { 
      // ... 
     } 

     return helper.InsertPerson(person); 
    } 
} 

,你甚至可以考慮IServiceCollection添加一個擴展方法,數據訪問層的類來幫助減少您的配置重複,尤其是當你添加更多的共同服務。

0

我發現了一個辦法做到這一點,但我仍然不相信這是最好的方式。在保存我的插入函數的類文件中,我添加了這個,以便當它從web api項目中調用時,來自web api的appcontext被傳遞給數據庫項目。隨着中說,我不知道是否有一個更優雅的方式

public class fnCommon 
{ 
    private readonly AppContext db; 

    public fnCommon(AppContext context) 
    { 
     this.db = context; 
    } 

    public int InsertPerson(tbl_Person person) 
    { 

     try 
     { 
      db.tbl_Person.Add(person); 
      db.SaveChanges(); 
      return person.PersonID; 
     } 

     catch 
     { 
      return 0; 
     } 
    } 
} 
+0

爲什麼不把EF上下文放在類庫中,而只是將連接字符串傳遞給它呢? – mason

+0

@mason你是什麼意思?我認爲通過在類庫的配置中它會是同樣的事情。你能告訴我一個你的意思嗎?我想我可能會過度複雜化這個問題哈哈 – chris

相關問題