Не удается разрешить DbContext в ASP.NET Core 2.0
Прежде всего, я пытаюсь засеять мою базу данных образцами данных. Я прочитал, что это способ сделать это (в Startup.Configure) (см. База данных семантики Core RC2 ASP.NET)
Я использую ASP.NET Core 2.0 с параметрами по умолчанию.
Как обычно, я регистрирую DbContext
в ConfigureServices
.
Но после этого в методе Startup.Configure, когда я пытаюсь разрешить его с помощью GetRequiredService
, он выдает это сообщение:
System.InvalidOperationException: "Не удается разрешить работу с областью действия" SGDTP.Infrastructure.Context.SGDTPContext" от root провайдер.
Мой класс запуска такой:
public abstract class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<SGDTPContext>(options => options.UseInMemoryDatabase("MyDatabase"))
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
SeedDatabase(app);
}
private static void SeedDatabase(IApplicationBuilder app)
{
using (var context = app.ApplicationServices.GetRequiredService<SGDTPContext>())
{
// Seed the Database
//...
}
}
}
Что я делаю неправильно?
Кроме того, это лучшее место для создания данных семян?
Ответы
Ответ 1
Вы регистрируете SGDTPContext
в качестве сервиса с областью действия, а затем пытаетесь получить к нему доступ за пределами области. Чтобы создать область внутри вашего метода SeedDatabase
, используйте следующее:
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<SGDTPContext>();
// Seed the database.
}
Благодарим @khellang за указание на метод расширения CreateScope
в комментариях, за комментарий @Tseng и ответ о том, как реализовать заполнение в EF Core 2.
Ответ 2
Эта ошибка получалась при чтении официального учебного пособия по ASP.Net MVC Core, в разделе, где вы должны добавить затравочные данные в свое приложение. Короче говоря, добавив эти две строки
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
чтобы класс SeedData
решил это за меня:
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
namespace MvcMovie.Models
{
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new MvcMovieContext(
serviceProvider.GetRequiredService<DbContextOptions<MvcMovieContext>>()))
{
// Look for any movies.
if (context.Movie.Any())
{
return; // DB has been seeded
}
...
Не могу сказать, ПОЧЕМУ, но это были два варианта, которые я получил после выбора варианта быстрого исправления Alt + Enter
.
Ответ 3
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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)
{
var key = Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value);
services.AddDbContext<DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableSensitiveDataLogging());
services.AddMvc();
services.AddTransient<Seed>();
services.AddCors();
services.AddScoped<IAuthRepository, AuthRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(Options =>
{
Options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
}
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env ,Seed seeder)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(builder =>
{
builder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
context.Response.AddApplicationError(error.Error.Message);
await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
}
});
});
}
seeder.SeedUser();
app.UseCors(x=>x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
app.UseMvc();
}
}
}