51 votes

Impossible de résoudre DbContext dans ASP.NET Core 2.0

Tout d'abord, j'essaie d'alimenter ma base de données avec des échantillons de données. J'ai lu que c'est la façon de procéder (en Startup.Configure ) (voir Base de données de semences ASP.NET Core RC2 )

J'utilise ASP.NET Core 2.0 avec les options par défaut.

Comme d'habitude, j'enregistre mon DbContext en ConfigureServices . Mais après cela, dans la méthode Startup.Configure, lorsque j'essaie de le résoudre en utilisant GetRequiredService il renvoie ce message :

System.InvalidOperationException : 'Cannot resolve scoped service 'SGDTP.Infrastructure.Context.SGDTPContext' de Root du fournisseur racine.'

Ma classe de démarrage est ainsi faite :

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
            //... 
        }
    }
}

Qu'est-ce que je fais de travers ? Par ailleurs, est-ce le meilleur endroit pour créer des données de semences ?

91voto

Kirk Larkin Points 29405

Vous vous inscrivez SGDTPContext en tant que cadré et tenter d'y accéder à l'extérieur d'un champ d'application. Pour créer un champ d'application à l'intérieur de votre SeedDatabase utiliser la méthode suivante :

using (var serviceScope = app.ApplicationServices.CreateScope())
{
    var context = serviceScope.ServiceProvider.GetService<SGDTPContext>();

    // Seed the database.
}

Merci à @khellang d'avoir signalé l'existence de la CreateScope dans les commentaires et au commentaire de @Tseng ainsi qu'à la méthode d'extension de répondre concernant la mise en œuvre de l'ensemencement dans EF Core 2.

3 votes

semble continuer à être l'approche recommandée pour l'ensemencement d'après ce que j'ai vu Enfin, pas exactement. Utiliser le scoped oui, mais pas dans la méthode Configure, à cause de la façon dont EF Core 2.0 fait la découverte et l'instanciation du DbContext au moment de la conception. Voir stackoverflow.com/a/45942026/455493 pour l'approche actuellement recommandée. Si vous continuez à ensemencer en Configure puis en exécutant la méthode dotnet ef migrations o dotnet ef database update exécutera également l'ensemencement, ce qui n'est pas du tout souhaitable lorsque l'on utilise les outils de la ligne de commande

2 votes

Pour information, il y a a CreateScope directement sur la méthode d'extension IServiceProvider pour que vous puissiez couper .GetRequiredService<IServiceScopeFactory>() et l'appeler directement :)

1voto

ojonugwa ochalifu Points 14742

J'ai obtenu cette erreur en suivant la procédure officielle ASP.Net MVC Core tutoriel dans la section où vous êtes censé ajouter des données semées à votre application. Pour faire court, il suffit d'ajouter ces deux lignes

 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.DependencyInjection;

à la SeedData a résolu le problème pour moi :

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
            }
  ...

Je ne peux pas vous dire POURQUOI, mais ce sont deux des options que j'ai obtenues en suivant l'instruction Alt + Enter solution rapide.

2 votes

Je travaille avec serviceProvider.CreateScope().ServiceProvider.GetRequiredService<DbContextOptions<AnyContext>>() ;

-1voto

SinaNasiri Points 77
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();
    }
}

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X