Database seeding avec EF Core

Découvrez comment initialiser efficacement vos bases de données avec Entity Framework Core. Un guide pratique pour générer des données de test cohérentes et accélérer votre cycle de développement.

Olivier Dupuy
31 juillet 2025

5

Vues

0

Commentaires

2

Min de lecture

Le database seeding est une étape cruciale dans le développement d'applications .NET modernes, permettant d'initialiser une base de données avec des données de test ou de configuration essentielles. Avec Entity Framework Core, Microsoft offre des mécanismes puissants pour gérer ce processus de manière élégante et maintenable. Dans cet article, nous explorerons en détail les différentes approches et bonnes pratiques pour implémenter le seeding de données avec EF Core.

Comprendre le Database Seeding

Le seeding de base de données consiste à pré-remplir des tables avec des données initiales nécessaires au fonctionnement de l'application. Ces données peuvent être :

  • Des données de configuration
  • Des données de référence (lookup data)
  • Des données de test pour le développement
  • Des données de démonstration

Méthodes de Seeding avec EF Core

1. Seeding via ModelBuilder


public class ApplicationDbContext : DbContext
{
    public DbSet Categories { get; set; }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configuration du seeding
        modelBuilder.Entity().HasData(
            new Category { Id = 1, Name = "Électronique" },
            new Category { Id = 2, Name = "Livres" },
            new Category { Id = 3, Name = "Vêtements" }
        );
    }
}

2. Seeding via Migrations


public partial class SeedInitialData : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.InsertData(
            table: "Categories",
            columns: new[] { "Id", "Name" },
            values: new object[] { 1, "Électronique" }
        );
    }

protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DeleteData( table: "Categories", keyColumn: "Id", keyValue: 1 ); } }

Bonnes Pratiques

Organisation du Code


// Configuration séparée pour chaque entité
public class CategoryConfiguration : IEntityTypeConfiguration
{
    public void Configure(EntityTypeBuilder builder)
    {
        builder.HasData(
            new Category { Id = 1, Name = "Électronique" },
            new Category { Id = 2, Name = "Livres" }
        );
    }
}

// Application dans le DbContext protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new CategoryConfiguration()); }

Gestion des Relations


public class ProductConfiguration : IEntityTypeConfiguration
{
    public void Configure(EntityTypeBuilder builder)
    {
        builder.HasData(
            new Product 
            { 
                Id = 1, 
                Name = "Laptop", 
                CategoryId = 1  // Référence à la catégorie "Électronique"
            }
        );
    }
}

Patterns d'Implémentation Avancés

Seeding Conditionnel


public static class DataSeeder
{
    public static async Task SeedDataAsync(IServiceProvider serviceProvider)
    {
        using var scope = serviceProvider.CreateScope();
        var context = scope.ServiceProvider.GetRequiredService();
        
        if (!await context.Categories.AnyAsync())
        {
            await context.Categories.AddRangeAsync(GetInitialCategories());
            await context.SaveChangesAsync();
        }
    }

private static IEnumerable GetInitialCategories() { return new List { new Category { Id = 1, Name = "Électronique" }, new Category { Id = 2, Name = "Livres" } }; } }

Tests et Validation


public class DataSeedingTests
{
    [Fact]
    public async Task SeedData_ShouldCreateInitialCategories()
    {
        // Arrange
        var options = new DbContextOptionsBuilder()
            .UseInMemoryDatabase("TestDb")
            .Options;

// Act using (var context = new ApplicationDbContext(options)) { await DataSeeder.SeedDataAsync(context); }

// Assert using (var context = new ApplicationDbContext(options)) { var categories = await context.Categories.ToListAsync(); Assert.Equal(2, categories.Count); Assert.Contains(categories, c => c.Name == "Électronique"); } } }

Considérations de Performance

Pour optimiser les performances du seeding, considérez les points suivants :

  • Utilisez AddRange() plutôt que des Add() multiples
  • Effectuez le seeding par lots (batching)
  • Désactivez le tracking si possible pendant le seeding


public static async Task SeedLargeDatasetAsync(ApplicationDbContext context)
{
    context.ChangeTracker.AutoDetectChangesEnabled = false;
    
    var categories = GenerateLargeDataset();
    await context.BulkInsertAsync(categories, options => {
        options.BatchSize = 1000;
        options.EnableStreaming = true;
    });
}

Conclusion

Le database seeding est une pratique essentielle dans le développement .NET moderne. Entity Framework Core offre plusieurs approches flexibles pour implémenter cette fonctionnalité. Les points clés à retenir sont :

  • Choisir la bonne approche selon vos besoins (ModelBuilder vs Migrations)
  • Organiser le code de seeding de manière maintenable
  • Gérer correctement les relations entre entités
  • Implémenter des tests appropriés
  • Optimiser les performances pour les grands jeux de données

En suivant ces recommandations, vous pourrez mettre en place un système de seeding robuste et efficace pour vos applications .NET.

Partager cet article
42
12

Commentaires (0)

Rejoignez la discussion

Connectez-vous pour partager votre avis et échanger avec la communauté

Première discussion

Soyez le premier à partager votre avis sur cet article !

À propos de l'auteur
Olivier Dupuy

Développeur passionné et contributeur actif de la communauté technique.

Profil
Articles similaires
API versioning strategies
02 août 2025 0
C# & .NET
Cryptographie post-quantique
02 août 2025 1
C# & .NET
Géolocalisation et cartes interactives
02 août 2025 0
C# & .NET
Navigation rapide
Commentaires (0)