65.9K
CodeProject 正在变化。 阅读更多。
Home

Seeding Data MVC 6 .NET Core 应用程序

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.69/5 (11投票s)

2019年8月15日

CPOL

3分钟阅读

viewsIcon

19213

downloadIcon

273

在启动时为 MVC 6 .NET Core 2.2 应用程序植入数据

目录

目标

就像 MVC 5 一样,我尝试启用自动迁移和植入默认数据,但似乎在 MVC 6 中行为有所改变,所以我认为我会分享这个技巧。

引言

在这里,我们将尝试学习在 MVC 6 ASP.NET Core 2.2 应用程序中植入数据。 这里,主要只有植入数据是我们范围的一部分。

使用 Visual Studio 2019,我使用默认模板创建了一个 .NET Core 2.2 Web 应用程序。 现在我的要求是在使用 Entity Framework 迁移创建数据库时植入一些默认数据。

为此,我们将在项目中创建一个名为 DbInitializer.cs 的类,并从 Startup.cs 类中调用其 Initialize 函数。

使用的组件

创建项目

在 Visual Studio 2019 中创建您的 Web 应用程序

选择 LanguageC#Project typeWeb,然后选择第一个模板,ASP.NET Core Web 应用程序,然后单击 Next

这是我的 appsettings.json 的样子

我将使用 localhost 作为我的服务器,并使用 Windows 身份验证。

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=Mvc.SeedingData;
                          Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

提供一个项目名称并选择物理路径,然后单击 Create。 它将创建项目,然后我们将在新项目中添加一个新的实体 Terminal。

public class Terminal
{
    public int Id { get; set; }

    public string Name { get; set; }

    public DateTime CreatedDate { get; set; }
}

这是我的 DbContext 类的样子

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
    {

    }

    public DbSet<Terminal> Terminal { get; set; }
}

现在,我们需要从 Migrations 文件夹删除所有内容,因为我们在 DbContext 类中添加了一个新实体,该实体应该在运行迁移和植入数据时在数据库中创建。

现在,我们需要运行 Add-migration 命令并为迁移命名。

注意Enable-migrations 命令已过时。

现在,我们可以运行 Update-database 命令来使用我们的代码优先模型创建数据库。 现在我们的数据库将就位,但目前表中没有任何数据。

DbInitializer 类

现在我已经在我的项目中添加了一个新类 DbInitializer.cs,我们可以通过 ApplicationDbContext 调用它来为数据库植入默认值。

我添加了默认的管理员角色和一个用户,所以当我们启动应用程序时,我们可以登录。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Mvc.SeedingData.Data;
using System;
using System.Linq;

namespace Mvc.SeedingData
{
    public static class DbInitializer
    {
        public static void Initialize(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
                context.Database.EnsureCreated();

                var _userManager = 
                         serviceScope.ServiceProvider.GetService<UserManager<IdentityUser>>();
                var _roleManager = 
                         serviceScope.ServiceProvider.GetService<RoleManager<IdentityRole>>();

                if (!context.Users.Any(usr => usr.UserName == "demo@test.com"))
                {
                    var user = new IdentityUser()
                    {
                        UserName = "demo@test.com",
                        Email = "demo@test.com",
                        EmailConfirmed = true,
                    };

                    var userResult = _userManager.CreateAsync(user, "P@ssw0rd").Result;
                }

                if (!_roleManager.RoleExistsAsync("Admin").Result)
                {
                    var role = _roleManager.CreateAsync
                               (new IdentityRole { Name = "Admin" }).Result;
                }

                var adminUser = _userManager.FindByNameAsync("demo@test.com").Result;
                var userRole = _userManager.AddToRolesAsync
                               (adminUser, new string[] { "Admin" }).Result;


                var terminal = context.Terminal
                                  .Where(x => x.Name == "Test").FirstOrDefault();

                if (terminal == null)
                {
                    terminal = new Terminal()
                    {
                        Name = "Test",
                        CreatedDate = DateTime.Now,
                    };

                    context.Terminal.Add(terminal);
                }

                context.SaveChanges();
            }
        }
    }
}

我希望仅从 Startup.cs 类在开发模式下运行 DbInitializer。 我们还需要将 IdentityUserIdentityRole 添加到服务中。

public void ConfigureServices(IServiceCollection services)
{
    ..........

    services.AddDefaultIdentity<IdentityUser>(options =>
    {
         options.Password.RequireDigit = true;
         options.Password.RequiredLength = 6;
         options.Password.RequireNonAlphanumeric = false;
         options.Password.RequireUppercase = false;
         options.Password.RequireLowercase = false;
    })
      .AddRoles<IdentityRole>()
      .AddDefaultUI(UIFramework.Bootstrap4)
      .AddEntityFrameworkStores<ApplicationDbContext>();

     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
     if (env.IsDevelopment())
     {
         app.UseDeveloperExceptionPage();
         app.UseDatabaseErrorPage();

         DbInitializer.Initialize(app);
     }

     ..........................
}

现在,当我们将在开发模式下启动我们的项目时,它将调用 DbInitializer 类Initialize 方法,并将数据插入到数据库表中。

结论

我们已经实现了在通过迁移创建数据库并在开发环境下启动项目时将默认数据植入到数据库中的目标。 我们试图仅限于植入默认数据的已定义范围。 如果您有任何问题,欢迎大家,感谢您的阅读....

历史

  • 2019年7月28日:初始版本
  • 2019年8月14日:改进了内容并添加了用于下载的源代码
© . All rights reserved.