Seeding data using DbContext

Let's continue by looking at another EF Core feature, which allows us to seed data. The seeding data technique facilitates testing environments to get a default snapshot of our integration test database.

Let's walk through an example of database seeding using .NET Core. First of all, let's create a new Data folder and add the JSON files that contain the test records. For brevity, I've included both the artist.json file and the genre.json file in the same snippet of code:

// Data/artist.json
[
{
"ArtistId": "3eb00b42-a9f0-4012-841d-70ebf3ab7474",
"ArtistName": "Kendrick Lamar",
"Items": null
},
{
"ArtistId": "f08a333d-30db-4dd1-b8ba-3b0473c7cdab",
"ArtistName": "Anderson Paak.",
"Items": null
}
]

// Data/genre.json
[
{
"GenreId": "c04f05c0-f6ad-44d1-a400-3375bfb5dfd6",
"GenreDescription": "Hip-Hop",
"Items": null
}
]

The aforementioned files contain data related to the Genre and Artist entities. In the same way, we can proceed by creating a new item.json file containing information about the Item entity:

//item.json
[
{
"Id": "86bff4f7-05a7-46b6-ba73-d43e2c45840f",
"Name": "DAMN.",
"Description": "DAMN. by Kendrick Lamar",
"LabelName": "TDE, Top Dawg Entertainment",
"Price": {
"Amount": 34.5,
"Currency": "EUR"
},
"PictureUri": "https://mycdn.com/pictures/45345345",
"ReleaseDate": "2017-01-01T00:00:00+00:00",
"Format": "Vinyl 33g",
"AvailableStock": 5,
"GenreId": "c04f05c0-f6ad-44d1-a400-3375bfb5dfd6",
"Genre": null,
"ArtistId": "3eb00b42-a9f0-4012-841d-70ebf3ab7474",
"Artist": null
},
{
"Id": "b5b05534-9263-448c-a69e-0bbd8b3eb90e",
"Name": "GOOD KID, m.A.A.d CITY",
"Description": "GOOD KID, m.A.A.d CITY. by Kendrick Lamar",
"LabelName": "TDE, Top Dawg Entertainment",
"Price": {
"Amount": 23.5,
"Currency": "EUR"
},
"PictureUri": "https://mycdn.com/pictures/32423423",
"ReleaseDate": "2016-01-01T00:00:00+00:00",
"Format": "Vinyl 33g",
"AvailableStock": 6,
"GenreId": "c04f05c0-f6ad-44d1-a400-3375bfb5dfd6",
"Genre": null,
"ArtistId": "3eb00b42-a9f0-4012-841d-70ebf3ab7474",
"Artist": null
},
{
"Id": "be05537d-5e80-45c1-bd8c-aa21c0f1251e",
"Name": "Malibu",
"Description": "Malibu. by Anderson Paak",
"LabelName": "Steel Wool/OBE/Art Club",
"Price": {
"Amount": 23.5,
"Currency": "EUR"
},
"PictureUri": "https://mycdn.com/pictures/32423423",
"ReleaseDate": "2016-01-01T00:00:00+00:00",
"Format": "Vinyl 43",
"AvailableStock": 3,
"GenreId": "c04f05c0-f6ad-44d1-a400-3375bfb5dfd6",
"Genre": null,
"ArtistId": "f08a333d-30db-4dd1-b8ba-3b0473c7cdab",
"Artist": null
}
]

These files hold some seed data to add to our database before each test. To read them, we need to include the Newtonsoft.Json package in the Catalog.Infrastructure.Tests project using the following command in the project folder:

dotnet add package Newtonsoft.Json

We should also ensure that the JSON files are copied to the bin folder during the compilation step by adding the following code to Catalog.Infrastructure.Tests.csproj:

...
<ItemGroup>
<None Update="Dataartist.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Datagenre.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Dataitem.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
..

The next step is to implement a method to read data from JSON and serialize it in our database context. Also, we should add the Microsoft.EntityFrameworkCore NuGet package to the test project using the following CLI command:

dotnet add package Microsoft.EntityFrameworkCore

The aforementioned package will provide the EF Core ModelBuilder type, which is used to generate the mock data used by our tests. Since we will use some of the code implemented in the Catalog.Infrastructure project, we should also add a reference to the test project using the following command in the root of the solution:

dotnet add ./tests/Catalog.Infrastructure.Tests reference ./src/Catalog.Infrastructure

After that, we can create a new extension method, named Seed<T>, inside a new Extensions folder in the Catalog.Infrastructure.Tests project:

using System.IO;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace Catalog.Infrastructure.Tests.Extensions
{
public static class ModelBuilderExtensions
{
public static ModelBuilder Seed<T>(this ModelBuilder
modelBuilder, string file) where T : class
{
using (var reader = new StreamReader(file))
{
var json = reader.ReadToEnd();
var data = JsonConvert.DeserializeObject<T[]>(json);
modelBuilder.Entity<T>().HasData(data);
}

return modelBuilder;
}
}
}

EF Core 2.1 has introduced a new way to perform data seeding in our database by exposing the HasData<T> method. The preceding code allows us to read a JSON file and serialize it into entities referred by modelBuilder. This approach provides a way to seed our mock database using the data written in the JSON files.

Finally, we can proceed by creating a new context in the Catalog.Infrastructure.Tests project named TestCatalogContext:

using Microsoft.EntityFrameworkCore;
using Catalog.Domain.Entities;
using Catalog.Infrastructure.Tests.Extensions;

namespace Catalog.Infrastructure.Tests
{
public class TestCatalogContext : CatalogContext
{
public TestCatalogContext(DbContextOptions<CatalogContext> options) : base(options)
{
}

protected override void OnModelCreating(ModelBuilder
modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Seed<Artist>("./Data/artist.json");
modelBuilder.Seed<Genre>("./Data/genre.json");
modelBuilder.Seed<Item>("./Data/item.json");
}
}
}

Here, TestCatalogContext class extends the CatalogContext class present in the Catalog.Infrastructure project, and overrides the OnModelCreating method to call the Seed<T> extension method on our entities. Consequently, when a consumer initializes the database using TestCatalogContext, it will have all the prepopulated data written in the JSON.

Note here that the TestCatalogContext extends the DbContextOptions<CatalogContext> option in the constructor in order to initialize the CatalogContext base class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.75.227