Optimisation des requêtes EF Core

Découvrez les techniques essentielles pour booster les performances de vos requêtes EF Core. Des conseils pratiques pour réduire le temps d'exécution et optimiser la consommation mémoire de votre a...

Olivier Dupuy
27 juillet 2025

9

Vues

0

Commentaires

2

Min de lecture

L'optimisation des performances des requêtes Entity Framework Core est un enjeu crucial pour tout développeur .NET cherchant à construire des applications performantes et scalables. Dans cet article, nous explorerons les techniques essentielles pour optimiser vos requêtes EF Core et améliorer significativement les performances de vos applications.

Concepts fondamentaux de l'optimisation EF Core

Avant de plonger dans les techniques d'optimisation, il est important de comprendre comment EF Core traduit nos requêtes LINQ en requêtes SQL et les exécute.

Le cycle de vie d'une requête EF Core

  • Création de l'expression LINQ
  • Traduction en SQL par le provider
  • Exécution de la requête
  • Matérialisation des résultats

Techniques d'optimisation essentielles

1. Chargement sélectif avec Select


// ❌ Mauvaise pratique : chargement de toutes les colonnes
var users = await context.Users.ToListAsync();

// ✅ Bonne pratique : chargement sélectif var userDtos = await context.Users .Select(u => new UserDto { Id = u.Id, Name = u.Name, Email = u.Email }) .ToListAsync();

2. Utilisation efficace des includes


// ❌ Chargement excessif
var orders = await context.Orders
    .Include(o => o.Customer)
    .Include(o => o.OrderItems)
    .ThenInclude(oi => oi.Product)
    .ToListAsync();

// ✅ Chargement optimisé avec filtrage var orders = await context.Orders .Include(o => o.Customer) .Include(o => o.OrderItems.Where(oi => oi.Quantity > 0)) .ThenInclude(oi => oi.Product) .Where(o => o.OrderDate >= DateTime.Today.AddDays(-30)) .ToListAsync();

3. Pagination efficace


public async Task> GetPagedResultAsync(
    IQueryable query,
    int pageNumber,
    int pageSize)
{
    return await query
        .Skip((pageNumber - 1)  pageSize)
        .Take(pageSize)
        .ToListAsync();
}

Bonnes pratiques et patterns

1. Utilisation du pattern Repository


public interface IRepository where T : class
{
    Task GetByIdAsync(int id);
    Task> GetAllAsync();
    Task AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(T entity);
}

public class Repository : IRepository where T : class { private readonly DbContext _context; private readonly DbSet _dbSet;

public Repository(DbContext context) { _context = context; _dbSet = context.Set(); }

public async Task GetByIdAsync(int id) { return await _dbSet.FindAsync(id); } // Autres implémentations... }

2. Mise en cache intelligente


public class CachedRepository : IRepository where T : class
{
    private readonly IRepository _repository;
    private readonly IMemoryCache _cache;
    private readonly string _cacheKey;

public CachedRepository( IRepository repository, IMemoryCache cache, string cacheKey) { _repository = repository; _cache = cache; _cacheKey = cacheKey; }

public async Task GetByIdAsync(int id) { return await _cache.GetOrCreateAsync( $"{_cacheKey}_{id}", async entry => { entry.SlidingExpiration = TimeSpan.FromMinutes(30); return await _repository.GetByIdAsync(id); }); } }

Optimisation des performances

1. Tracking des entités


// ❌ Avec tracking (par défaut)
var users = await context.Users.ToListAsync();

// ✅ Sans tracking pour les requêtes en lecture seule var users = await context.Users .AsNoTracking() .ToListAsync();

2. Compilation des requêtes


private static readonly Func> GetCustomerById =
    EF.CompileAsyncQuery((ApplicationDbContext context, int id) =>
        context.Customers
            .Include(c => c.Orders)
            .FirstOrDefault(c => c.Id == id));

// Utilisation var customer = await GetCustomerById(context, 1);

Tests et validation


public class QueryOptimizationTests
{
    [Fact]
    public async Task GetCustomers_WithPagination_ReturnsCorrectPage()
    {
        // Arrange
        using var context = new TestDbContext();
        var repository = new CustomerRepository(context);

// Act var customers = await repository.GetPagedResultAsync(1, 10);

// Assert Assert.Equal(10, customers.Count()); } }

Considérations de performance

  • Utilisez SQL Server Profiler pour analyser les requêtes générées
  • Activez le logging des requêtes en développement
  • Surveillez les performances avec Application Insights
  • Implémentez des health checks pour monitorer la base de données

Conclusion

L'optimisation des requêtes EF Core est un aspect crucial du développement .NET moderne. En appliquant les techniques présentées dans cet article, vous pourrez significativement améliorer les performances de vos applications. N'oubliez pas de toujours mesurer l'impact de vos optimisations et de les adapter aux besoins spécifiques de votre projet.

Ressources complémentaires :

  • Documentation officielle EF Core
  • GitHub EF Core
  • Blogs de la communauté .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 3
C# & .NET
Cryptographie post-quantique
02 août 2025 3
C# & .NET
Géolocalisation et cartes interactives
02 août 2025 3
C# & .NET
Navigation rapide
Commentaires (0)