如何在Entity Framework Core 2中播种?
我有两张桌子,我想用种子填充它。
我在Ubuntu中使用ASP.NET Core 2。
如何填充两个表的数据,哪一个通过外键与其他表连接? 流量计有很多笔记和笔记属于flometer。 我想做这样的事情,但它应该存储在数据库中。
new Flowmeter {Make="Simple model name",SerialNum=45, Model="Lor Avon", Notes = new List() { new Note(){Value=45,CheckedAt=System.DateTime.Now}, new Note(){Value=98,CheckedAt=System.DateTime.Now} } }
从entity framework核心2.1开始 ,现在有一种新的种子数据播种方法。 在您的DbContext
类中重写OnModelCreating
:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasData(new Blog { BlogId = 1, Url = "http://sample.com" }); }
对于相关实体,请使用匿名类并指定相关实体的外键:
modelBuilder.Entity().HasData( new {BlogId = 1, PostId = 1, Title = "First post", Content = "Test 1"}, new {BlogId = 1, PostId = 2, Title = "Second post", Content = "Test 2"});
官方文档已更新 。
这是我的EF Core 2.0解决方案,改编自https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#move-database-initialization-code
在program.cs中
public class Program { public static void Main(string[] args) { BuildWebHost(args).Seed().Run(); }
….
然后我的播种机课
public static class DatabaseSeedInitializer { public static IWebHost Seed(this IWebHost host) { using (var scope = host.Services.CreateScope()) { var serviceProvider = scope.ServiceProvider; try { Task.Run(async () => { var dataseed = new DataInitializer(); await dataseed.InitializeDataAsync(serviceProvider); }).Wait(); } catch (Exception ex) { var logger = serviceProvider.GetRequiredService>(); logger.LogError(ex, "An error occurred seeding the DB."); } } return host; } }
tl; dr :看看我的dwCheckApi项目 ,看看我是如何实现它的。
正如其他人所说,你可以从JSON或类似的东西中读取你的种子数据(如果你愿意的话,它可以是源代码控制的)。
我在项目中实现它的方法是在Startup类的Configure
方法中调用一个方法(仅在开发时):
if (env.IsDevelopment()) { app.EnsureDatabaseIsSeeded(false); }
它调用以下内容:
public static int EnsureDatabaseIsSeeded(this IApplicationBuilder applicationBuilder, bool autoMigrateDatabase) { // seed the database using an extension method using (var serviceScope = applicationBuilder.ApplicationServices .GetRequiredService().CreateScope()) { var context = serviceScope.ServiceProvider.GetService(); if (autoMigrateDatabase) { context.Database.Migrate(); } return context.EnsureSeedData(); } }
我的DbContext是DwContext类型,它是一个扩展EF Core DbContext
类型的类
EnsureSeedData
扩展方法如下所示:
public static int EnsureSeedData(this DwContext context) { var bookCount = default(int); var characterCount = default(int); var bookSeriesCount = default(int); // Because each of the following seed method needs to do a save // (the data they're importing is relational), we need to call // SaveAsync within each method. // So let's keep tabs on the counts as they come back var dbSeeder = new DatabaseSeeder(context); if (!context.Books.Any()) { var pathToSeedData = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookSeedData.json"); bookCount = dbSeeder.SeedBookEntitiesFromJson(pathToSeedData).Result; } if (!context.BookCharacters.Any()) { characterCount = dbSeeder.SeedBookCharacterEntriesFromJson().Result; } if (!context.BookSeries.Any()) { bookSeriesCount = dbSeeder.SeedBookSeriesEntriesFromJson().Result; } return bookCount + characterCount + bookSeriesCount; }
此应用程序旨在显示书籍,字符和系列之间的关系。 这就是为什么有三个播种机。
其中一个播种方法如下所示:
public async Task SeedBookEntitiesFromJson(string filePath) { if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentException($"Value of {filePath} must be supplied to {nameof(SeedBookEntitiesFromJson)}"); } if (!File.Exists(filePath)) { throw new ArgumentException($"The file { filePath} does not exist"); } var dataSet = File.ReadAllText(filePath); var seedData = JsonConvert.DeserializeObject>(dataSet); // ensure that we only get the distinct books (based on their name) var distinctSeedData = seedData.GroupBy(b => b.BookName).Select(b => b.First()); _context.Books.AddRange(distinctSeedData); return await _context.SaveChangesAsync(); }
这里可能有一些代码不是很好,但它可能是你反弹的起点。
因为仅在开发环境中调用ASPNETCORE_ENVIRONMENT=Development dotnet run
,所以您需要确保应用程序以这种方式启动(如果从命令行开始,您可以使用ASPNETCORE_ENVIRONMENT=Development dotnet run
以确保它在开发中启动)。
这也意味着您需要一种不同的方法来为生产中的数据库播种。 在dwCheckApi中,我有一个可以调用种子数据库的控制器(看一下DatabaseController的SeedData方法 ,看看我是怎么做的)。
我在json中创建了种子,只需批量添加我的Asp.net核心启动
非常类似于https://garywoodfine.com/how-to-seed-your-ef-core-database/
还没有找到开箱即用的解决方案。
我遇到了同样的问题,我通过以下方式修复了播种:
首先,我将public static bool AllMigrationsApplied(this DbContext context)
的public static bool AllMigrationsApplied(this DbContext context)
添加到我的模型中。
然后我实现了一个服务范围来播种db – >请参阅此博客
然后我使用NBuilder和Faker按照本博客的教程制作了一个public static void EnsureSeedData
和代码来生成测试数据
我希望这将有助于人们为他们的项目实现自动化测试种子。 目前我正忙着自己实现这个,当我有时间时,我将发布一些代码示例来说明如何执行此操作。
- 从csproj引用xproj
- 使用Novell.Directory.Ldap.NETStandard库进行C#netcore ldap身份validation
- 在.NET核心中获取类的公共属性
- 在ASP.NET Core Web API中上载文件和JSON
- VS.NET 2017强制在ASP.NET 2.0 Core应用程序中使用StackExchange.Redis 1.2.4.0
- 无法加载文件或程序集System.Net.Http版本4.1.1.0
- 如何添加通用dependency injection
- Net Core Connection String Dapper视觉工作室2017
- 用于TcpClient的.NET核心替代品