在数据访问层内获取Db上下文

时间:2016-11-29 09:28:52

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

我在EF-Core上遇到了一些我想弄清楚的问题 我使用MVC Core应用程序中的启动代码来初始化db上下文 这是我的数据库上下文:

ByteArrayEncoder

}

启动代码:

public class AccountsDBContext : DbContext
{
    public AccountsDBContext(DbContextOptions<AccountsDBContext> options)
        :base(options)
    {

    }

    // ...

在所有示例中,我看到DB Context是通过构造函数传递给控制器​​(我假设通过依赖注入)并从那里传递到其他实体\层。

 public void ConfigureServices(IServiceCollection services)
 {
        // Inject the account db
        services.AddDbContext<AccountsDBContext>(options =>
           options.UseMySQL(Configuration.GetConnectionString("AccountsStore")));

        // ...

但是,我不太喜欢db上下文将成为控制器成员的想法。
我真的更喜欢在数据访问层中获取db上下文,而不是将其传递到存储库类 有没有办法在数据访问层内部获取上下文?(据我所知,没有IServiceCollection,IApplicationBuilder,IServiceScopeFactory)

3 个答案:

答案 0 :(得分:0)

我明白你要做什么。我做到了这一点。关键是在DAL中创建一个使用IServiceCollection的静态类。然后在这里你将我的上下文添加到我的中,这是一种对待我的前端甚至不知道实体框架,nethier做我的业务层:

public static IServiceCollection RegisterRepositoryServices(this IServiceCollection services)
    {
        services.AddIdentity<ApplicationUser, IdentityRole<int>>(
            config => { config.User.RequireUniqueEmail = true;
                config.Cookies.ApplicationCookie.LoginPath = "/Account/Login";
                config.Cookies.ApplicationCookie.AuthenticationScheme = "Cookie";
                config.Cookies.ApplicationCookie.AutomaticAuthenticate = false;
                config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
                {
                    OnRedirectToLogin = async ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/visualjobs") && ctx.Response.StatusCode == 200)
                        {
                            ctx.Response.StatusCode = 401;
                        }
                        else
                        {
                            ctx.Response.Redirect(ctx.RedirectUri);
                        }
                        await Task.Yield();
                    }
                };
            }).AddEntityFrameworkStores<VisualJobsDbContext, int>()
          .AddDefaultTokenProviders();

        services.AddEntityFramework().AddDbContext<VisualJobsDbContext>();

        services.AddScoped<IRecruiterRepository, RecruiterRepository>();
        services.AddSingleton<IAccountRepository, AccountRepository>();

        return services;
    }

然后在我的服务层我有另一个静态类。我的服务层有一个对存储库层的引用,我在这里注册存储库服务(将存储库引导到服务层),就像这样,然后我在UI中再次执行相同操作:

服务层代码:

public static class ServiceCollectionExtensions
{
    public static IServiceCollection RegisterServices(this IServiceCollection services)
    {
        services.RegisterRepositoryServices();
        services.AddScoped<IRecruiterService, RecruiterService>();
        services.AddSingleton<IAccountService, AccountService>();

        return services;
    }
}

存储库层中的魔术:

public partial class VisualJobsDbContext : IdentityDbContext<ApplicationUser, IdentityRole<int>, int>
{
    private IConfigurationRoot _config;

    public VisualJobsDbContext() { }

    public VisualJobsDbContext(IConfigurationRoot config, DbContextOptions<VisualJobsDbContext> options) : base(options)
    {
        _config = config;
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        optionsBuilder.UseSqlServer(@_config["ConnectionStrings:VisualJobsContextConnection"]);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {....

答案 1 :(得分:0)

将存储库/ DAL实现注入到控制器中,并将DbContext注入到repo构造函数中。只要注册了相应的类,

答案 2 :(得分:0)

怎么样?

DALAccount.cs

public class DALAccount
{
     private AccountsDBContext _db;
     public DALAccount(AccountsDBContext db)
     {
          _db = db;
     }
     public IQueryable<User> Get()
         => _db.User.AsQueryable();
}

您的Api

public class AccountsController : Controller
{
     private AccountsDBContext _db;

     public AccountsController(AccountsDBContext context)
     {
          this._db = context;
     }
     public IActionResult Index()
     {
          DALAccount dal = new DALAccount(_db);
          var list = dal.Get();
     }
}