[英]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.