Entity Framework- 无法引用实体上下文
Entity Framework- Cannot reference entity context
上下文:
public class EntityContext : DbContext
{
public EntityContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var cascadeTables = modelBuilder.Model.GetEntityTypes()
.SelectMany(foreignKeysTables => foreignKeysTables.GetForeignKeys())
.Where(foreignKeysTables => !foreignKeysTables.IsOwnership &&
foreignKeysTables.DeleteBehavior == DeleteBehavior.Cascade);
foreach (var table in cascadeTables)
{
table.DeleteBehavior = DeleteBehavior.Restrict;
}
base.OnModelCreating(modelBuilder);
}
DbSet<Account> Accounts { get; set; }
}
使用上下文保存到数据库中:
using (var context = new EntityContext()) //error on EntityContext()
{
context.Account.Add(acc); //error on Account because EntityContext can't be referenced
context.SaveChanges();
}
我无法引用上下文,因为它需要一个参数(DbContextOptions 选项),我怎样才能通过它来保存我的帐户实例?
谢谢。
您可以对 IOC 容器使用依赖注入(构造函数注入),例如,
public class YourClass {
private readonly EntityContext context;
public YourClass(EntityContext context) {
this.context = context;
}
public void YourMethod(){
context.Account.Add(acc);
context.SaveChanges();
}
}
Most popular IOC containers,
- Unity Container
- Castle Windsor
- NInject
- Structure Map
您需要使用 IOC 容器指定如何创建 EntityContext 实例,如单例、作用域或瞬态。像这样;
var container = new YourContainer();
container.Register<DbContext>(Lifestyle.Scoped);
您需要在 DI 容器中注册您的上下文,然后它可以被注入到您需要的任何对象的构造函数中。而且您不需要每次都手动构建上下文。
See more here
您需要配置 DbContextOptions,因为 DbContext 需要 DbContextOptions 才能正常工作。 DbContextOptions 包含数据库提供程序和连接字符串等信息。
可以通过以下方式配置:
1) 使用依赖注入容器时
如果您在 ASP.Net 核心中使用默认的依赖注入容器,您可以在方法 ConfigureServices 中的 Startup.cs 中添加以下代码。
public void ConfigureServices(IServiceCollection services)
{
// ...other service registration
services.AddDbContext<EntityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
并且在appsettings.json中,您需要定义连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "Server=servername;Database=dbname;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
然后,依赖注入容器将在创建对象时向实体上下文提供选项。
public class EntityContext : DbContext
{
public EntityContext(DbContextOptions options) : base(options)
{
}
.....
}
然后,你可以在你的class中使用如下:
public class AccountRepository
{
private readonly EntityContext context;
public AccountRepository(EntityContext entityContext)
{
this.context = entityContext;
}
public void Save()
{
context.Account.Add(acc);
context.SaveChanges();
}
}
2) OnConfiguring 选项 - 在上下文中初始化 DbContextOptions(当不使用依赖注入容器时):
public class EntityContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
options.UseSqlServer(connectionString);
}
.....
}
然后,在您的 class 中,您可以在不传递参数的情况下实例化上下文:
using (var context = new EntityContext())
{
context.Account.Add(acc);
context.SaveChanges();
}
3) 在实例化Context时将DbContextOptions作为构造函数参数传递(当不使用依赖注入容器时):
var optionsBuilder = new DbContextOptionsBuilder<EntityContext>();
optionsBuilder.UseSqlServer(connectionString);
using (var context = new EntityContext(optionsBuilder.Options))
{
context.Account.Add(acc);
context.SaveChanges();
}
上下文:
public class EntityContext : DbContext
{
public EntityContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var cascadeTables = modelBuilder.Model.GetEntityTypes()
.SelectMany(foreignKeysTables => foreignKeysTables.GetForeignKeys())
.Where(foreignKeysTables => !foreignKeysTables.IsOwnership &&
foreignKeysTables.DeleteBehavior == DeleteBehavior.Cascade);
foreach (var table in cascadeTables)
{
table.DeleteBehavior = DeleteBehavior.Restrict;
}
base.OnModelCreating(modelBuilder);
}
DbSet<Account> Accounts { get; set; }
}
使用上下文保存到数据库中:
using (var context = new EntityContext()) //error on EntityContext()
{
context.Account.Add(acc); //error on Account because EntityContext can't be referenced
context.SaveChanges();
}
我无法引用上下文,因为它需要一个参数(DbContextOptions 选项),我怎样才能通过它来保存我的帐户实例?
谢谢。
您可以对 IOC 容器使用依赖注入(构造函数注入),例如,
public class YourClass {
private readonly EntityContext context;
public YourClass(EntityContext context) {
this.context = context;
}
public void YourMethod(){
context.Account.Add(acc);
context.SaveChanges();
}
}
Most popular IOC containers,
- Unity Container
- Castle Windsor
- NInject
- Structure Map
您需要使用 IOC 容器指定如何创建 EntityContext 实例,如单例、作用域或瞬态。像这样;
var container = new YourContainer();
container.Register<DbContext>(Lifestyle.Scoped);
您需要在 DI 容器中注册您的上下文,然后它可以被注入到您需要的任何对象的构造函数中。而且您不需要每次都手动构建上下文。 See more here
您需要配置 DbContextOptions,因为 DbContext 需要 DbContextOptions 才能正常工作。 DbContextOptions 包含数据库提供程序和连接字符串等信息。
可以通过以下方式配置:
1) 使用依赖注入容器时
如果您在 ASP.Net 核心中使用默认的依赖注入容器,您可以在方法 ConfigureServices 中的 Startup.cs 中添加以下代码。
public void ConfigureServices(IServiceCollection services)
{
// ...other service registration
services.AddDbContext<EntityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
并且在appsettings.json中,您需要定义连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "Server=servername;Database=dbname;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
然后,依赖注入容器将在创建对象时向实体上下文提供选项。
public class EntityContext : DbContext
{
public EntityContext(DbContextOptions options) : base(options)
{
}
.....
}
然后,你可以在你的class中使用如下:
public class AccountRepository
{
private readonly EntityContext context;
public AccountRepository(EntityContext entityContext)
{
this.context = entityContext;
}
public void Save()
{
context.Account.Add(acc);
context.SaveChanges();
}
}
2) OnConfiguring 选项 - 在上下文中初始化 DbContextOptions(当不使用依赖注入容器时):
public class EntityContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
options.UseSqlServer(connectionString);
}
.....
}
然后,在您的 class 中,您可以在不传递参数的情况下实例化上下文:
using (var context = new EntityContext())
{
context.Account.Add(acc);
context.SaveChanges();
}
3) 在实例化Context时将DbContextOptions作为构造函数参数传递(当不使用依赖注入容器时):
var optionsBuilder = new DbContextOptionsBuilder<EntityContext>();
optionsBuilder.UseSqlServer(connectionString);
using (var context = new EntityContext(optionsBuilder.Options))
{
context.Account.Add(acc);
context.SaveChanges();
}