2
votes

I'm playing around with the new ASP.NET 5 beta 8 and having trouble when I have two dbcontext.

I have the following project structure.

-Data(Identity 3 db with other entities)
-Resources (Contains a db with translations)
-WebApp 

Stripped away some code in Startup.cs in WebApp

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

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

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ResourceDbContext>(opt => opt.UseSqlServer(Configuration["Data:Resources:ConnectionString"]));

        services.AddTransient<IResourceDbContext, ResourceDbContext>();
        services.AddTransient<IDatabaseContext, DatabaseContext>();
}

In both ResourceDbContext and DatabaseContext I do the following

    public ResourceDbContext(DbContextOptions options) : base(options)
    {
        _connectionString = ((SqlServerOptionsExtension)options.Extensions.First()).ConnectionString;
    }


    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlServer(_connectionString);
    }

However when I read my connectionstrings from appsettings.json I receive the correct values in ConfigureServices. But the DbContextOptions only contains the latest loaded value, in this case the connectionstring for Resources. So both dbcontext establishes a connection to Resource db.

I'm unable to find any information about this.

3

3 Answers

3
votes

All you need to do is indicate that DbContextOptions is a generic type:

public ResourceDbContext(DbContextOptions<ResourceDbContext> options) : base(options)
{

}

Now the dependency injection system can find the right dependency (DbContextOptions options) at the moment it creates ResourceDbContext and injects it into the constructor.

See implementation AddDbContext method


For Miroslav Siska:

public class GetHabitsIdentity: IdentityDbContext<GetHabitsUser, IdentityRole, string> where TUser : IdentityUser
{
    public GetHabitsIdentity(DbContextOptions<GetHabitsIdentity> options)
        :base(options)
    {

    }        
}
2
votes

You can use EF with different coonection strings. I don't see the error in your code. I used this setup.

services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationContext>(options =>
                options.UseSqlServer(Configuration["Data:OtherConnection:ConnectionString"]));

In the DBContext class

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Localizations> Localizations { get; set; }
    private string _connectionString;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        _connectionString = ((SqlServerOptionsExtension)optionsBuilder.Options.Extensions.First()).ConnectionString;
        Console.WriteLine($"ApplicationDbContext{_connectionString}");
    }


public class ApplicationContext : DbContext
{
    private string _connectionString;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        _connectionString = ((SqlServerOptionsExtension)optionsBuilder.Options.Extensions.First()).ConnectionString;
        Console.WriteLine($"ApplicationContext{_connectionString}");
    }
}
0
votes

Thank you for big help!!!

Complete solution:

  public class TenantDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string>
{
    private string _connectionString { get; set; }  

    public TenantDbContext(DbContextOptions<TenantDbContext> options) : base(options)  
    {
        this._connectionString = "Connection String";
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    { 
        optionsBuilder.UseSqlServer(_connectionString); 
    }
}

ASP.NET 5 DI working for injecting DbContext and UserManager to controller. Now it is possible to login and register with multiple databases... Now I need only check how to inject connection string here: this._connectionString = "Connection String"; But it is simple... Thank you again!