Как исправить «нулевое исключение» при заполнении и инициализации базы данных в ядре asp.net (Entity Framework) - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь заполнить мои данные при первом запуске, используя функцию конфигурации в Startup.cs

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

app.SeedData();, затем вызывает функцию SeedData в DataSeeder.cs для инициализации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);
    }

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Вместо этого вместо InvalidOperationException, говоря: «Не зарегистрирован сервис для типа« BrandTest.Data.ApplicationDbContext ».»

Для этого сообщения об ошибке необходимозарегистрируйте свой dbcontext в Startup.cs как

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

И вы не можете разрешить службу от корневого провайдера, измените 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;
    }
}
0 голосов
/ 19 февраля 2019

Вам нужно добавить свой контекст к 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>();
...
        }

это класс запуска из одного из моих проектов:

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...