简体   繁体   English

实体框架6-播种数据库引发System.NullReferenceException

[英]entity framework 6 - seeding database throws System.NullReferenceException

I'm using .net core 2 and entityframework 6.2. 我正在使用.net core 2和EntityFramework 6.2。 I'm trying to seed database with some needed base data. 我正在尝试为数据库提供一些必需的基础数据。

  1. I didn't find the Database.SetInitializer method. 我没有找到Database.SetInitializer方法。 So I googled and found another way to seed my database in Main method of Program class (as shown below). 因此,我用Google搜索并找到了另一种在Program类的Main方法中播种数据库的方法(如下所示)。
  2. I used below code to seed my database but when executing SaveChange method of DbContext , always I get NullReferenceException error. 我使用下面的代码为数据库设置种子,但是当执行DbContext SaveChange方法时,总是出现NullReferenceException错误。
  3. I'm using the same database as Identity uses. 我正在使用与Identity使用的数据库相同的数据库。 Does it affect the result? 它会影响结果吗?

Program 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();
}

Exception: 例外:

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

Startup 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: ApplicationDbContext类:

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; }
}

BW I'm using EntityFramework 6.2.0 & Microsoft.EntityFrameworkCore.Tools 2.1.1 (maybe useful info) BW我正在使用EntityFramework 6.2.0和Microsoft.EntityFrameworkCore.Tools 2.1.1(可能是有用的信息)

Thanks for spending time. 感谢您的宝贵时间。

Use this code: 使用此代码:

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();
}

Code from : https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/working-with-sql?view=aspnetcore-2.0&tabs=aspnetcore2x 来自的代码: https : //docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-mvc-app/working-with-sql?view=aspnetcore-2.0&tabs=aspnetcore2x

OK! 好! I found the reason. 我找到了原因。 In Main method when I'm creating a new entity of type Province, assigning value to its key parameter causes the error. 在Main方法中,当我创建Province类型的新实体时,为其键参数分配值会导致错误。 This solves the problem: 这样可以解决问题:

context.Provinces.Add(new Models.Province
{
     //ID = 1,
     Name = "TEST"
});

But yet I'm really angry because the exception thrown doesn't show the real error! 但是我真的很生气,因为抛出的异常没有显示出真正的错误!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM