entity framework 6 - 播种数据库抛出 System.NullReferenceException
entity framework 6 - seeding database throws System.NullReferenceException
我正在使用 .net core 2 和 entityframework 6.2。我正在尝试使用一些需要的基础数据来为数据库播种。
- 我没有找到 Database.SetInitializer 方法。所以我用谷歌搜索并找到了另一种在
Program
class 的 Main
方法中播种我的数据库的方法(如下所示)。
- 我使用下面的代码为我的数据库设置种子,但是在执行
DbContext
的 SaveChange
方法时,总是出现 NullReferenceException 错误。
- 我使用的数据库与 Identity 使用的数据库相同。对结果有影响吗?
程序class:
public class Program
{
public static void Main(string[] args)
{
//BuildWebHost(args).Run();
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<ApplicationDbContext>();
context.Provinces.Add(new Models.Province
{
ID = 1,
Name = "TEST"
});
context.SaveChanges(); // <= ERROR
//DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occured while seeding the database.");
}
}
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
异常:
Message: "Object reference not set to an instance of an object."
Source: "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore"
StackTrace:
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.System.IObserver<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.OnNext(KeyValuePair`2 keyValuePair)
at System.Diagnostics.DiagnosticListener.Write(String name, Object value)
at Microsoft.EntityFrameworkCore.Internal.CoreLoggerExtensions.SaveChangesFailed(IDiagnosticsLogger`1 diagnostics, DbContext context, Exception exception)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at Invitation.Program.Main(String[] args) in d:\Projects\Invitation\Invitation\Program.cs:line 29
InnerException: null
启动class:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddCustomIdentity()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IdentityErrorDescriber, FaIdentityErrorDescriber>();
services.ConfigureCustomApplicationCookie();
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
});
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connection));
services.AddSingleton<IEmailSender, EmailSender>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public DbSet<Province> Provinces { get; set; }
}
B.W. 我正在使用 EntityFramework 6.2.0 & Microsoft.EntityFrameworkCore.Tools 2.1.1(可能有用的信息)
感谢您抽出时间。
使用此代码:
public class Program
{
public static void Main(string[] args)
{
//BuildWebHost(args).Run();
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
using (var context = new ApplicationDbContext(
services.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
context.Provinces.Add(new Models.Province
{
ID = 1,
Name = "TEST"
});
context.SaveChanges();
}
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occured while seeding the database.");
}
}
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
好的!我找到了原因。在 Main 方法中,当我创建 Province 类型的新实体时,为其关键参数赋值会导致错误。这解决了问题:
context.Provinces.Add(new Models.Province
{
//ID = 1,
Name = "TEST"
});
但是我真的很生气,因为抛出的异常并没有显示真正的错误!
我正在使用 .net core 2 和 entityframework 6.2。我正在尝试使用一些需要的基础数据来为数据库播种。
- 我没有找到 Database.SetInitializer 方法。所以我用谷歌搜索并找到了另一种在
Program
class 的Main
方法中播种我的数据库的方法(如下所示)。 - 我使用下面的代码为我的数据库设置种子,但是在执行
DbContext
的SaveChange
方法时,总是出现 NullReferenceException 错误。 - 我使用的数据库与 Identity 使用的数据库相同。对结果有影响吗?
程序class:
public class Program
{
public static void Main(string[] args)
{
//BuildWebHost(args).Run();
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<ApplicationDbContext>();
context.Provinces.Add(new Models.Province
{
ID = 1,
Name = "TEST"
});
context.SaveChanges(); // <= ERROR
//DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occured while seeding the database.");
}
}
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
异常:
Message: "Object reference not set to an instance of an object."
Source: "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore"
StackTrace:
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.System.IObserver<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.OnNext(KeyValuePair`2 keyValuePair)
at System.Diagnostics.DiagnosticListener.Write(String name, Object value)
at Microsoft.EntityFrameworkCore.Internal.CoreLoggerExtensions.SaveChangesFailed(IDiagnosticsLogger`1 diagnostics, DbContext context, Exception exception)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at Invitation.Program.Main(String[] args) in d:\Projects\Invitation\Invitation\Program.cs:line 29
InnerException: null
启动class:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddCustomIdentity()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IdentityErrorDescriber, FaIdentityErrorDescriber>();
services.ConfigureCustomApplicationCookie();
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
});
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connection));
services.AddSingleton<IEmailSender, EmailSender>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public DbSet<Province> Provinces { get; set; }
}
B.W. 我正在使用 EntityFramework 6.2.0 & Microsoft.EntityFrameworkCore.Tools 2.1.1(可能有用的信息)
感谢您抽出时间。
使用此代码:
public class Program
{
public static void Main(string[] args)
{
//BuildWebHost(args).Run();
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
using (var context = new ApplicationDbContext(
services.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
context.Provinces.Add(new Models.Province
{
ID = 1,
Name = "TEST"
});
context.SaveChanges();
}
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occured while seeding the database.");
}
}
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
好的!我找到了原因。在 Main 方法中,当我创建 Province 类型的新实体时,为其关键参数赋值会导致错误。这解决了问题:
context.Provinces.Add(new Models.Province
{
//ID = 1,
Name = "TEST"
});
但是我真的很生气,因为抛出的异常并没有显示真正的错误!