簡體   English   中英

在asp.net核心(Entity Framework)中播種和初始化數據庫時,如何解決“空異常”

[英]How to fix “Null exception” when seeding and initialising the database in asp.net core (Entity Framework)

我正在嘗試使用Startup.cs中的configure函數來為我的數據首次運行

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
       .
       .
        app.SeedData();
    }

app.SeedData(); 然后在DataSeeder.cs中調用SeedData函數以初始化ApplicatonDbContext。

public static class DataSeeder
{
    public static async void SeedData(this IApplicationBuilder app)
    {
        var dbManager = app.ApplicationServices.GetService<ApplicationDbContext>();
        dbManager.Database.Migrate();

        Brand Addiction;
        Addiction = new Brand()
        {
            BrandName = "Addiction"
        };
        dbManager.Brands.Add(Addiction);
        dbManager.SaveChanges();
        return;
    }
}

當代碼嘗試運行dbManager.Database.Migrate(); ,則拋出NullReferenceException,表明dbManager為null。 我嘗試在ApplicationDbContext.cs的第一行上放置一個斷點,好像它沒有運行它。 有什么方法可以修復它嗎?

我見過其他人使用app.ApplicationServices.GetRequiredService<ApplicationDbContext>(); 而不是app.ApplicationServices.GetService<ApplicationDbContext>(); 我嘗試更改它,但得到一個InvalidOperationException,說“沒有注冊類型'BrandTest.Data.ApplicationDbContext'的服務。”

我的ApplicationDbContext.cs代碼順便說一句

using BrandTest.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BrandTest.Data
{
public class ApplicationDbContext : DbContext
{
    public DbSet<Brand> Brands { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=DESKTOP-ABCDE\SQLEXPRESS;Database=PetStoreDB;Trusted_Connection=True;MultipleActiveResultSets=True");
        base.OnConfiguring(optionsBuilder);
    }

您必須將上下文添加到Startup類中的DI(相同的類,其中您具有Configure()方法)

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
...
            services.AddScoped<ApplicationDbContext>();
...
        }

這是我的項目之一中的Startup類:

public class Startup
{
    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", false, true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public static IConfiguration Configuration { get; private set; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddOptions<ActivationServiceOptions>(Configuration);

        services.AddScoped<ActivationServiceContext>();
        services.AddOptions<ActivationServiceContextOptions>(Configuration);

        services.AddOptions<KeysProviderOptions>(Configuration);
        services.AddScoped<IEncryptor, Encryptor>();

        LandingLoggingStartup.ConfigureServices(services, Configuration);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
        else
            app.UseHsts();

        LandingLoggingStartup.Configure(app);
        app.UseMvc();
    }
}

相反,InvalidOperationException表示“沒有注冊類型'BrandTest.Data.ApplicationDbContext'的服務。”

對於此錯誤消息,您需要在Startup.cs注冊dbcontext,例如

services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(
        Configuration.GetConnectionString("MySqlConnection"));
});

而且您無法從根提供者解析服務, DataSeeder像這樣更改DataSeeder

public static class DataSeeder
{
    public static async void SeedData(this IApplicationBuilder app)
    {
        var dbManager = app.ApplicationServices.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>();
        dbManager.Database.Migrate();
        Brand Addiction;
        Addiction = new Brand()
        {
            BrandName = "Addiction"
        };
        dbManager.Brands.Add(Addiction);
        dbManager.SaveChanges();
        return;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM