【问题标题】:ASP.NET Core 2 Seed Database [duplicate]ASP.NET Core 2 种子数据库 [重复]
【发布时间】:2018-02-23 15:35:37
【问题描述】:

我已经在 SO 上看到了一些类似的例子,但我对这种语言的了解还不够,还没有看到我做错了什么。我拼凑了一个演示以了解更多信息,但我在为我的数据库播种时遇到了问题。

我收到以下错误:

InvalidOperationException:无法从根提供程序解析范围服务“demoApp.Models.AppDbContext”。

Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, ServiceProvider serviceProvider)

以下是有问题的三个文件:

模型/AppDbContext.cs

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

    }
    public DbSet<Product> Products{ get; set; }
    public DbSet<Category> Categories { get; set; }
}

模型/DBInitializer.cs

public static class DbInitializer
{
    public static void Seed(IApplicationBuilder applicationBuilder)
    {
        //I'm bombing here
        AppDbContext context = applicationBuilder.ApplicationServices.GetRequiredService<AppDbContext>();

        if (!context.Products.Any())
        {
            // Add range of products
        }

        context.SaveChanges();
    }

    private static Dictionary<string, Category> _categories;
    public static Dictionary<string, Category> Categories
    {
        get
        {
            if (_categories == null)
            {
               // Add categories...
            }

            return _categories;
        }
    }
}

Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ICategoryRepository, CategoryRepository>();
    services.AddTransient<IProductRepository, ProductRepository>();

    services.AddDbContext<AppDbContext>(options => 
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
        app.UseStatusCodePages();
        
        // Kersplat!
        DbInitializer.Seed(app);
    }
    else ...
    
    app.UseStaticFiles();
    app.UseMvc(routes => {...});
}

有人可以帮助解释我做错了什么以及如何纠正这种情况吗?

【问题讨论】:

    标签: c# asp.net .net .net-core-2.0


    【解决方案1】:

    在 ASP.NET Core 2.0 中建议进行以下更改。 (在 startup.cs 中播种适用于 Core 1.x。对于 2.0 进入 Program.cs,修改 Main 方法以在应用程序启动时执行以下操作: 从依赖注入容器中获取数据库上下文实例。 调用种子方法,将上下文传递给它。 当种子方法完成时释放上下文。 (这是来自 Microsoft 网站的示例。https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro

    public static void Main(string[] args)
    {
    var host = BuildWebHost(args);
    
    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<yourDBContext>();
            DbInitializer.Seed(context);//<---Do your seeding here
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding the database.");
        }
    }
    
    host.Run();
    }
    

    【讨论】:

    • 为什么要修改Main?有没有提到这是首选的参考资料?
    • 它在上面代码正下方的链接文章中提到了它。 “在较早的教程中,您可能会在 Startup.cs 的 Configure 方法中看到类似的代码。我们建议您仅使用 Configure 方法来设置请求管道。应用程序启动代码属于 Main 方法。”
    • 注意:需要以下 using 语句才能使 CreateScope 方法可用:using Microsoft.Extensions.DependencyInjection;
    【解决方案2】:

    从原始答案更新:

    对于 .NET Core 2.0,请查看 this answer

    原答案:

    我也不是 .NET Core 专家,但这可能是您的解决方案。

    DBInitializer.cs

        public static void Seed(IApplicationBuilder applicationBuilder)
        {
            using (var serviceScope = applicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                    .CreateScope())
            {
                AppDbContext context = serviceScope.ServiceProvider.GetService<AppDbContext>();
    
                if (!context.Products.Any())
                {
                    // Seed Here
                }
    
                context.SaveChanges();
            }
        }
    

    错误提示上下文应该是作用域的。

    另外,如果您还没有这样做,我会看看 Introduction to Dependency Injection in ASP.NET Core 文档,更具体地说,是 Service Lifetimes and Registration Options 部分。

    【讨论】:

    • 我重新运行了迁移,更新了数据库和按预期播种的数据库。我非常感谢您提供的链接。非常感谢。
    • 你是最棒的,谢谢!
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 2017-07-29
    • 2013-11-13
    • 1970-01-01
    • 2014-06-27
    • 2016-09-18
    相关资源
    最近更新 更多