如何在Controller之外使用EF DbConext?

时间:2017-07-21 11:42:09

标签: c# asp.net entity-framework asp.net-core

我正在构建作为模拟器的ASP.Net应用程序,许多操作将在Controller之外作为单独的威胁发生,但我很难在Controller之外创建DbContext连接。我知道我可以使用OnConfiguring(DbContextOptionsBuilder optionsBuilder),但它并不是我最优雅的方式。

我通过这样的事情应该有效:

public class SimRepository : ISimRepository
{
    public IConfiguration _configuration;
    public DbContextOptionsBuilder _dbOptions;

    public SimRepository(IConfiguration configuration)
    {
        _configuration = configuration;

        _dbOptions = new DbContextOptionsBuilder();
        _dbOptions.UseSqlServer(_configuration.GetConnectionString("DefaultConnection"));
    }

    public void LatheIn()
    {
        using (AppDbContext db = new AppDbContext(_dbOptions.Options))
        {

        }
    }
}

但是我收到了这个错误:

Argument 1: cannot convert from Microsoft.EntityFrameworkCore.DbContextOptions' to Microsoft.EntityFrameworkCore.DbContextOptions<Simulator_Line.Server.AppDbContext>

在初创公司:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<AppDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddMvc();

    //Enable use of appsettings.json outside of Startup.cs
    services.AddSingleton(Configuration);
    services.AddSingleton<IConfiguration>(Configuration);
}

如果我的方法不正确,我可以接受更改。

修改

    public class LatheController : Controller
{
    private readonly AppDbContext _dbContext;
    private readonly SimRepository _simRrepo;

    public LatheController(AppDbContext dbContext, SimRepository latheRepo)
    {
        _dbContext = dbContext;
        _simRrepo = latheRepo;
    }

    [HttpGet]
    public IEnumerable<Lathe> GetLathes()
    {
        _simRrepo.LatheIn();



        return _dbContext.Lathes;
    }
}

1 个答案:

答案 0 :(得分:0)

您已在服务集合中注册了DbContext。只需将它注入依赖类,以便在解析依赖类时解析它

public class SimRepository : ISimRepository {
    public readonly AppDbContext db;

    public SimRepository(AppDbContext db) {
        this.db = db;
    }

    public void LatheIn() {
        //...use db
    }
}

更新

您可以创建工厂

public interface IAppDbContextFactory {
    AppDbContext Create();
}

用于根据需要创建实例

public class SimRepository : ISimRepository {
    public readonly IAppDbContextFactory factory;

    public SimRepository(IAppDbContextFactory factory) {
        this.factory = factory;
    }

    public void LatheIn() {
        using (AppDbContext db = factory.Create()) {
            //...use db
        }
    }
}

工厂实施可能看起来像

public class AppDbContextFactory : IAppDbContextFactory {
    private readonly IServiceProvider servideProvider;

    public AppDbContextFactory(IServiceProvider servideProvider) {
        this.serviceProvider = serviceProvider;
    }

    public AppDbContext Create() {
        return serviceProvider.GetService<AppDbContext>();
    }
}

确保使用服务集合注册您的类型。

public void ConfigureServices(IServiceCollection services) {
    // Add framework services.
    services.AddDbContext<AppDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddMvc();

    //Enable use of appsettings.json outside of Startup.cs
    services.AddSingleton(Configuration);
    services.AddSingleton<IConfiguration>(Configuration);

    services.AddSingleton<IAppDbContextFactory, AppDbContextFactory>();
    services.AddTransient<ISimRepository, SimRepository>();
}

这样可以在需要的地方使用

public class SomeController : Controller {
    private readonly ISimRepository simRepository;
    public SomeController(ISimRepository simRepository) {
        this.simRepository = simRepository;
    }

    public IActionResult SomeAction() {
        simRepository.LatheIn();
        return Ok();
    }
}