使用 EF7 和 VNext 访问 DBContext
Access DBContext using EF7 and VNext
在我的 MVC 6 项目中,我有 ApplicationDBContext
class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
}
}
这已添加到我的服务中 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
//Other configurations removed for brevity
}
现在当我创建一个新的 Controller 时,它会询问我是否要使用 Entity Framework,我可以选择我的数据上下文。创建该控制器时,使用我假设的依赖注入将上下文传递到构造函数中。
public class CompanyController : Controller
{
private ApplicationDbContext _context;
public CompanyController(ApplicationDbContext context)
{
_context = context;
}
}
现在,我不想在控制器中进行所有数据库交互,而是在我的其他 classes 中进行。我想不通的是如何从我的其他 classes 获取 ApplicationDbContext。从控制器传递它显然是行不通的,因为 classes 可以从控制器以外的其他地方调用。
如果我只是尝试 new ApplicationDbContext();
,我会收到以下错误:
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.
我觉得这应该很简单,但我完全迷失在这里。
ASP.NET核心基于依赖注入,因为你的上下文已经添加到你的依赖容器中,当你的控制器被实例化时,它会被框架自动注入。
根据评论编辑:
您可以设置 classes 以支持 DI,假设您有两个 class。一个取决于你的上下文,然后第二个取决于你的上下文和你的第一个 class :
public class MyClass
{
private ApplicationDbContext _context;
public MyClass(ApplicationDbContext context)
{
_context = context;
}
}
public class AnotherClass
{
private ApplicationDbContext _context;
private MyClass _myClass;
public AnotherClass(ApplicationDbContext context, MyClass myClass)
{
_context = context;
_myClass = myClass;
}
}
在启动时将您的 classes 作为临时依赖项添加到服务集合中,并让服务提供商为您解决它们的依赖项:
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddTransient<MyClass>();
services.AddTransient<AnotherClass>();
//Other configurations removed for brevity
}
更改您的控制器以接受 MyClass 作为注入的依赖项:
public class CompanyController : Controller
{
private ApplicationDbContext _context;
private MyClass _myClass;
public CompanyController(ApplicationDbContext context, MyClass myClass)
{
_context = context;
_myClass = myClass;
}
}
你也可以有另一个控制器,将 AnotherClass 作为注入依赖:
public class AnotherController : Controller
{
private AnotherClass _anotherClass;
public AnotherController(AnotherClass anotherClass)
{
_anotherClass = anotherClass;
// _anotherClass will have both ApplicationDbContext and MyClass injected by the service provider
}
}
您应该阅读 K. Scott Allen 的 docs of dependency injection of ASP.NET Core, it could help to understand basics of DI. Another article,其中解释了处理 DI 时的一些不良做法。
您可以创建一个服务 class 以与控制器相同的方式接收 DbContext。
public class SomeService
{
private ApplicationDbContext MyDbContext { get; set; }
public SomeService(ApplicationDbContext dbContext)
{
MyDbContext = dbContext;
}
public void MethodName()
{
// You can now do MyDbContext.SomeDomainModel
}
}
然后在您的 ConfigureServices
方法中注册 Startup.cs 中的服务。
public void ConfigureServices(IServiceCollection services) {
// <snipped>
services.AddTransient<SomeService>();
}
现在,在 CompanyController
中,您可以在 SomeService
的构造函数中添加另一个参数,就像 ApplicationDbContext
.
一样
public class CompanyController : Controller
{
private ApplicationDbContext _context;
private SomeService _someService;
public CompanyController(ApplicationDbContext context, SomeService someService)
{
_context = context;
_someService = someService;
}
}
综上所述,我认为在控制器操作中执行逻辑以构建 ViewModel、访问 DbContext 没有任何问题。 DbContext 将您的业务逻辑(在控制器中)与 DAL 分开。有些人可能不同意我的看法,但您不需要添加额外的服务来进一步分离它们。您的操作方法中的大部分代码对于该操作都是唯一的,不会被其他操作重用。 IMO,那些 是要投入服务的代码片段。诸如发送电子邮件之类的事情。
在我的 MVC 6 项目中,我有 ApplicationDBContext
class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
}
}
这已添加到我的服务中 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
//Other configurations removed for brevity
}
现在当我创建一个新的 Controller 时,它会询问我是否要使用 Entity Framework,我可以选择我的数据上下文。创建该控制器时,使用我假设的依赖注入将上下文传递到构造函数中。
public class CompanyController : Controller
{
private ApplicationDbContext _context;
public CompanyController(ApplicationDbContext context)
{
_context = context;
}
}
现在,我不想在控制器中进行所有数据库交互,而是在我的其他 classes 中进行。我想不通的是如何从我的其他 classes 获取 ApplicationDbContext。从控制器传递它显然是行不通的,因为 classes 可以从控制器以外的其他地方调用。
如果我只是尝试 new ApplicationDbContext();
,我会收到以下错误:
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.
我觉得这应该很简单,但我完全迷失在这里。
ASP.NET核心基于依赖注入,因为你的上下文已经添加到你的依赖容器中,当你的控制器被实例化时,它会被框架自动注入。
根据评论编辑:
您可以设置 classes 以支持 DI,假设您有两个 class。一个取决于你的上下文,然后第二个取决于你的上下文和你的第一个 class :
public class MyClass
{
private ApplicationDbContext _context;
public MyClass(ApplicationDbContext context)
{
_context = context;
}
}
public class AnotherClass
{
private ApplicationDbContext _context;
private MyClass _myClass;
public AnotherClass(ApplicationDbContext context, MyClass myClass)
{
_context = context;
_myClass = myClass;
}
}
在启动时将您的 classes 作为临时依赖项添加到服务集合中,并让服务提供商为您解决它们的依赖项:
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddTransient<MyClass>();
services.AddTransient<AnotherClass>();
//Other configurations removed for brevity
}
更改您的控制器以接受 MyClass 作为注入的依赖项:
public class CompanyController : Controller
{
private ApplicationDbContext _context;
private MyClass _myClass;
public CompanyController(ApplicationDbContext context, MyClass myClass)
{
_context = context;
_myClass = myClass;
}
}
你也可以有另一个控制器,将 AnotherClass 作为注入依赖:
public class AnotherController : Controller
{
private AnotherClass _anotherClass;
public AnotherController(AnotherClass anotherClass)
{
_anotherClass = anotherClass;
// _anotherClass will have both ApplicationDbContext and MyClass injected by the service provider
}
}
您应该阅读 K. Scott Allen 的 docs of dependency injection of ASP.NET Core, it could help to understand basics of DI. Another article,其中解释了处理 DI 时的一些不良做法。
您可以创建一个服务 class 以与控制器相同的方式接收 DbContext。
public class SomeService
{
private ApplicationDbContext MyDbContext { get; set; }
public SomeService(ApplicationDbContext dbContext)
{
MyDbContext = dbContext;
}
public void MethodName()
{
// You can now do MyDbContext.SomeDomainModel
}
}
然后在您的 ConfigureServices
方法中注册 Startup.cs 中的服务。
public void ConfigureServices(IServiceCollection services) {
// <snipped>
services.AddTransient<SomeService>();
}
现在,在 CompanyController
中,您可以在 SomeService
的构造函数中添加另一个参数,就像 ApplicationDbContext
.
public class CompanyController : Controller
{
private ApplicationDbContext _context;
private SomeService _someService;
public CompanyController(ApplicationDbContext context, SomeService someService)
{
_context = context;
_someService = someService;
}
}
综上所述,我认为在控制器操作中执行逻辑以构建 ViewModel、访问 DbContext 没有任何问题。 DbContext 将您的业务逻辑(在控制器中)与 DAL 分开。有些人可能不同意我的看法,但您不需要添加额外的服务来进一步分离它们。您的操作方法中的大部分代码对于该操作都是唯一的,不会被其他操作重用。 IMO,那些 是要投入服务的代码片段。诸如发送电子邮件之类的事情。