英文:
ASP.NET Core 6 MVC : data not being seeded
问题
我已经包括了我的DataSeeder.cs
文件和Program.cs
中相关的代码,但数据并没有被种植到PostgreSQL数据库中,也没有出现任何错误。
我尝试在命令行中运行以下命令:
dotnet run seeddata
但没有起作用。
我在运行上述命令或应用程序时查看了控制台,但没有显示任何错误信息。
你的代码有什么问题呢?
英文:
I've included my DataSeeder.cs
and the relevant code in the Program.cs
below, but the data is not being seeded to a Postgresql database and I am not getting any errors.
I tried running it from the command line with:
dotnet run seeddata
but that didn't work.
I looked at the console when running the above command or running the application but there were no errors indicated.
Any idea what is wrong with my code?
DataSeeder.cs
using ContactPro.Data;
using ContactPro.Models;
using Microsoft.AspNetCore.Identity;
namespace ContactPro.Helpers
{
public class DataSeeder
{
private readonly ApplicationDbContext _dbContext;
private readonly UserManager<AppUser> _userManager;
private static string appUserId;
public DataSeeder(ApplicationDbContext dbContext, UserManager<AppUser> userManager)
{
_dbContext = dbContext;
_userManager = userManager;
}
public async Task SeedDataAsync()
{
await SeedUsersAsync();
await SeedContactsAsync();
await SeedCategoriesAsync();
}
private async Task SeedUsersAsync()
{
if (_dbContext.Users.Any())
{
return;
}
var demoUser = new AppUser()
{
UserName = "demouser@mail.com",
Email = "demouser@mail.com",
FirstName = "Demo",
LastName = "User",
EmailConfirmed = true,
};
await _userManager.CreateAsync(demoUser, "xxxxxx");
appUserId = _dbContext.Users.FirstOrDefault(u => u.Email == "demouser@mail.com").Id;
}
private async Task SeedContactsAsync()
{
if (!_dbContext.Contacts.Any())
{
var contact = new List<Contact>()
{
new Contact()
{
FirstName = "John",
LastName = "Dickens",
Address1 = "12 Main St.",
City = "Concord",
States = ContactPro.Enums.States.NH,
ZipCode = 03101,
Email = "john@mail.com",
AppUserId = appUserId,
}
};
await _dbContext.Contacts.AddRangeAsync(contact);
_dbContext.SaveChanges();
}
}
private async Task SeedCategoriesAsync()
{
if (!_dbContext.Categories.Any())
{
var category = new List<Category>()
{
new Category()
{
Name = "_UnCategorized",
AppUserId = appUserId
},
};
await _dbContext.Categories.AddRangeAsync(category);
_dbContext.SaveChanges();
}
}
}
}
Program.cs
builder.Services.AddTransient<DataSeeder, DataSeeder>();
if (args.Length == 1 && args[0].ToLower() == "seeddata")
{
SeedData(app);
}
void SeedData(IHost app)
{
var scopedFactory = app.Services.GetService<IServiceScopeFactory>();
using (var scope = scopedFactory.CreateScope())
{
var service = scope.ServiceProvider.GetService<DataSeeder>();
service.SeedDataAsync();
}
}
SeedData(app);
答案1
得分: 1
Your SeedData method in Program.cs should look like this:
async Task SeedData(IHost app)
{
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var dataSeeder = services.GetRequiredService<DataSeeder>();
await dataSeeder.SeedDataAsync();
}
}
And the way to call this method should be:
if (args.Length == 1 && args[0].ToLower() == "seeddata")
{
SeedData(app).GetAwaiter().GetResult();
}
The .GetAwaiter().GetResult() part is a way to block and wait for a Task to complete. It's not usually recommended because it blocks the calling thread until the Task completes, but in this case, it's necessary because the Main method can't be async, and we need to ensure the database seeding completes before the application starts running.
Also, make sure your DbContext is saving changes after adding the new entries. It seems like you're missing _dbContext.SaveChangesAsync()
after _userManager.CreateAsync(demoUser, "Abc&123!")
in SeedUsersAsync
.
英文:
Looking at your code, you seem to be trying to seed the database in the Startup, but you're doing it asynchronously and not awaiting the result. This is a common error in seed code, because the Main method in Program.cs is not asynchronous.
Your SeedData method in Program.cs should look like this:
async Task SeedData(IHost app)
{
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var dataSeeder = services.GetRequiredService<DataSeeder>();
await dataSeeder.SeedDataAsync();
}
}
And the way to call this method should be:
{
SeedData(app).GetAwaiter().GetResult();
}
The .GetAwaiter().GetResult() part is a way to block and wait for a Task to complete. It's not usually recommended because it blocks the calling thread until the Task completes, but in this case, it's necessary because the Main method can't be async and we need to ensure the database seeding completes before the application starts running.
Also, make sure your DbContext is saving changes after adding the new entries. It seems like you're missing _dbContext.SaveChangesAsync() after _userManager.CreateAsync(demoUser, "Abc&123!") in SeedUsersAsync.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论