I'm trying to use two different databases in one api.
These are the contexts:
public class DatabaseOneDBContext : DbContext, IDatabaseOneDBContext
{
public DatabaseOneDBContext(DbContextOptions<DatabaseOneDBContext> options)
: base(options)
{
}
public DbSet<Alena> Alena { get; set; }
public async Task<int> SaveChangesAsyncOne()
{
return await base.SaveChangesAsync();
}
}
public class DatabaseTwoDBContext : DbContext, IDatabaseTwoDBContext
{
private readonly IDatabaseTwoDBContext _context;
public DatabaseTwoDBContext(IDatabaseTwoDBContext context)
{
this._context = context;
}
public DbSet<Cortana> Cortana { get; set; }
public async Task<int> SaveChangesAsyncTwo()
{
return await base.SaveChangesAsync();
}
}
appsettings.json
"ConnectionStrings": {
"ConnectionDB1": "Server=.\\SQLEXPRESS;Database=DatabaseOne;Trusted_Connection=True;MultipleActiveResultSets=true",
"ConnectionDB2": "Server=.\\SQLEXPRESS;Database=DatabaseTwo;Trusted_Connection=True;MultipleActiveResultSets=true"
},
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Forecast.DatabaseOne;
using Forecast.DatabaseOne.Contracts;
using Forecast.ServiceOne.Contracts;
using Forecast.ServiceOne;
using Serilog;
using Forecast.DatabaseTwo;
using Forecast.DatabaseTwo.Contracts;
using Forecast.ServiceTwo.Contracts;
using Forecast.ServiceTwo;
namespace Forecast.Web
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseOneDBContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionDB1"),
ef => ef.MigrationsAssembly("Forecast.DatabaseOne")));
services.AddScoped<IDatabaseOneDBContext>(provider => provider.GetService<DatabaseOneDBContext>());
services.AddDbContext<DatabaseTwoDBContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionDB2"),
ef => ef.MigrationsAssembly("Forecast.DatabaseTwo")));
services.AddScoped<IDatabaseTwoDBContext>(provider => provider.GetService<DatabaseTwoDBContext>());
services.AddTransient<IAlenaService, AlenaService>();
services.AddTransient<ICortanaService, CortanaService>();
services.AddApiVersioning(apiVerConfig =>
{
apiVerConfig.AssumeDefaultVersionWhenUnspecified = true;
apiVerConfig.DefaultApiVersion = new ApiVersion(new DateTime(2022, 1, 22));
});
services.AddHealthChecks()
.AddDbContextCheck<DatabaseOneDBContext>();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1a", new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "ForecastService - Alena Web API",
Version = "v1a",
Description = "test service"
});
});
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseHealthChecks("/checkhealth");
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1a/swagger.json", "Alena API v1a");
});
}
}
}
When I use this
add-migration -context DatabaseOneDBContext
update-database -context DatabaseOneDBContext
it works and default project is DatabaseOne, but when I try to do the same thing for DatabaseTwoDBContext (I change the default project to DatabaseTwo), it just sleeps the process and I have to restart my PC so I can try again.
Help me solve this
AddScoped<IDatabaseOneDBContext>to inject your context.AddDbContext<>does that for you in the background. Not sure whether this is what is causing your error however, so not posting it as an answer. But it might be your migration getting confused with which instance to use.