如何使用 Entity Framework 在 .NET Core 6 中播种数据?

问题描述 投票:0回答:6

我知道如何使用我的 startup.cs 类和创建一些初始数据的

Seeder
方法将数据播种到
Seed()
文件中旧版
.NET 5.0
的数据库中。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, Seeder seeder)
{
   seeder.Seed();

   ..............
   // other configurations
}

如何在 .NET 6.0 中执行此操作?没有地方可以添加我的

Seeder
类作为参数。

c# entity-framework asp.net-core-6.0
6个回答
19
投票

我解决了类似的问题如下:

程序.cs (.NET 6)

...
builder.Services.AddScoped<IDbInitializer, DbInitializer>(); //can be placed among other "AddScoped" - above: var app = builder.Build();   

...    
SeedDatabase(); //can be placed above app.UseStaticFiles();
...    
    void SeedDatabase() //can be placed at the very bottom under app.Run()
    {
        using (var scope = app.Services.CreateScope())
        {
            var dbInitializer = scope.ServiceProvider.GetRequiredService<IDbInitializer>();
            dbInitializer.Initialize();
        }
    }

18
投票

我以前从未使用过你的解决方案。这就是我正在做的事情,

public class DataContext: DbContext
{
    public DataContext(DbContextOptions options) : base(options)
    {
        
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        new DbInitializer(modelBuilder).Seed();
    }
    
    // Db sets
}

还有

public class DbInitializer
{
    private readonly ModelBuilder modelBuilder;

    public DbInitializer(ModelBuilder modelBuilder)
    {
        this.modelBuilder = modelBuilder;
    }

    public void Seed()
    {
        modelBuilder.Entity<User>().HasData(
               new User(){ Id = 1.... },
               new User(){ Id = 2.... },

        );
    }
}

然后运行命令

dotnet ef migrations add .......

创建迁移文件

还有

dotnet ef database update

更新数据库


17
投票

.NET 6.0

使用这些链接获取详细版本:

Program.cs

var builder = WebApplication.CreateBuilder(args);

//Add services to the container.
builder.Services.AddDbContext<YourDbContext>(
    optionsBuilder => optionsBuilder.UseSqlServer("Your connection string goes here") //install - Microsoft.EntityFrameworkCore.SqlServer to use ".UseSqlServer" extension method
builder.Services.AddScoped<DbInitializer>();

var app = builder.Build();

//Configure the HTTP-request pipeline
if (app.Environment.IsDevelopment())
{
    app.UseItToSeedSqlServer();    //custom extension method to seed the DB
    //configure other services
}

app.Run();

DbInitializerExtension.cs

internal static class DbInitializerExtension
{
    public static IApplicationBuilder UseItToSeedSqlServer(this IApplicationBuilder app)
    {
        ArgumentNullException.ThrowIfNull(app, nameof(app));

        using var scope = app.ApplicationServices.CreateScope();
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<YourDbContext>();
            DbInitializer.Initialize(context);
        }
        catch (Exception ex)
        {

        }

        return app;
    }
}

DbInitializer.cs

internal class DbInitializer
{
    internal static void Initialize(YourDbContext dbContext)
    {
        ArgumentNullException.ThrowIfNull(dbContext, nameof(dbContext));
        dbContext.Database.EnsureCreated();
        if (dbContext.Users.Any()) return;

        var users = new User[]
        {
            new User{ Id = 1, Name = "Bruce Wayne" }
            //add other users
        };

        foreach(var user in users)
            dbContext.Users.Add(user);

        dbContext.SaveChanges();
    }
}

4
投票

就我而言,我使用 Microsoft.AspNetCore.Identity 并需要使用种子方法使用数据库中的默认值初始化应用程序。

builder.Services.AddScoped<UserManager<ApplicationUser>>();
builder.Services.AddScoped<RoleManager<IdentityRole>>();

在包含

的行之后
var app = builder.Build();

我已经调用了种子方法:

using (var scope = app.Services.CreateScope())
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<Usuario>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
await DefaultRoles.SeedAsync(roleManager);
await DefaultAdmin.SeedAsync(userManager);
}

4
投票

Seeder.cs

public static class Seeder
{
public static void Initialize(DatabaseContext context)
{
    context.Database.EnsureCreated();
    //your seeding data here
    context.SaveChanges();

}
}

程序.cs

var app = builder.Build();
SeedDatabase();

void SeedDatabase()
    using(var scope = app.Services.CreateScope())
    try{
        var scopedContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
        Seeder.Initialize(scopedContext);
        }
catch{
    throw;
}

就像使用 DI 之前一样简单。


0
投票

我知道有关 .NET 6.0 的问题,但我认为它具有相同的概念。

就我而言,我使用的是 .NET 8.0,并使用 Microsoft.AspNetCore.Identity,因此我需要使用种子方法在数据库中使用默认值(Defulat 用户和 Defulat 角色)来初始化应用程序。

首先,我创建一个类,并在其中定义一个枚举“包含我拥有的角色”,并编写与默认用户“姓名、电子邮件、密码、角色...等”相关的主要信息。

然后我创建一个名为

ApplicationDbContextSeed
的类:

public class ApplicationDbContextSeed
    {
        public async Task<bool> SeedEssentialsAsync(UserManager<ApplicationUser> userManager,
                                                    RoleManager<IdentityRole> roleManager)
        {
            //Seed Roles
            await roleManager.CreateAsync(new IdentityRole(Authorization.Roles.SuperUser.ToString()));
            await roleManager.CreateAsync(new IdentityRole(Authorization.Roles.User.ToString())); 
    
             
    
            //Seed Default User
            var defaultUser = new ApplicationUser
            {
                Firstname= Authorization.default_Firstname,
                Lastrname= Authorization.default_Lastname,
                UserName = Authorization.default_username,
                Email = Authorization.default_email,
                EmailConfirmed = true,
                PhoneNumberConfirmed = true,
                IsPasswordChanged = true, 
                IsActive = true
            };
            if (userManager.Users.All(u => u.Id != defaultUser.Id))
            {
                await userManager.CreateAsync(defaultUser, Authorization.default_password);
                await userManager.AddToRoleAsync(defaultUser, Authorization.superuser_role.ToString());
            }
    
            return true;
        }
    }

在 Program.cs 中:

var app = builder.Build();
if (args.Length == 1 && args[0].ToLower() == "seeddata")
 await SeedData(app);

async Task SeedData(IHost app)
{
    var scopedFactory = app.Services.GetService<IServiceScopeFactory>();
    using (var scope = scopedFactory?.CreateScope())
    {
        var service = scope?.ServiceProvider.GetService<ApplicationDbContextSeed>();
        var userManager = scope?.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        var roleManager = scope?.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        await service.SeedEssentialsAsync(userManager, roleManager);
    }
}

在我创建第一次迁移

Add-Migration InitialCreate
并使用语句
Update-database
创建数据库后,表是空的,我使用语句
dotnet run seeddata

用初始数据填充它

希望它可以帮助任何陷入这部分的人。

© www.soinside.com 2019 - 2024. All rights reserved.