using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; namespace Api; // Runs each endpoint's query once and writes the SQL EF Core sent to the server. public static class SqlDump { public static async Task RunAsync(string connectionString, string path) { await using var writer = new StreamWriter(path, append: false); var options = new DbContextOptionsBuilder() .UseNpgsql(connectionString) .LogTo(line => writer.WriteLine(line), [RelationalEventId.CommandExecuted], LogLevel.Information) .Options; await using var db = new AppDbContext(options); var efVersion = typeof(DbContext).Assembly .GetCustomAttribute()?.InformationalVersion; writer.WriteLine($"-- Microsoft.EntityFrameworkCore {efVersion}"); writer.WriteLine($"-- runtime {Environment.Version}"); writer.WriteLine(); writer.WriteLine("-- GET /orders?customerId=42&page=1"); await OrderQueries.PageAsync(db, 42, 1, CancellationToken.None); writer.WriteLine(); writer.WriteLine("-- GET /orders/report?from=2026-10-01&days=3"); var from = new DateTime(2026, 10, 1, 0, 0, 0, DateTimeKind.Utc); await OrderQueries.RangeAsync(db, from, from.AddDays(3), CancellationToken.None); writer.WriteLine(); writer.WriteLine("-- GET /orders?customerId=42&page=1, with four references"); await OrderQueries.PageWithReferencesAsync(db, 42, 1, CancellationToken.None); writer.WriteLine(); writer.WriteLine("-- GET /orders/report?from=2026-10-01&days=3, with four references"); await OrderQueries.RangeWithReferencesAsync(db, from, from.AddDays(3), CancellationToken.None); writer.WriteLine(); // The same two required references in both orders, to show which join EF Core 11 keeps. var firstOrders = db.Orders.Where(o => o.Id <= 20); writer.WriteLine("-- Two required references, Customer included first"); await firstOrders .Include(o => o.Customer) .Include(o => o.ShippingAddress) .Include(o => o.Payments) .AsSplitQuery() .AsNoTracking() .ToListAsync(); writer.WriteLine(); writer.WriteLine("-- Two required references, ShippingAddress included first"); await firstOrders .Include(o => o.ShippingAddress) .Include(o => o.Customer) .Include(o => o.Payments) .AsSplitQuery() .AsNoTracking() .ToListAsync(); } }