SQL brut, procédures stockées et interpolation
Exécutez du SQL brut en toute sécurité avec FromSqlRaw, FromSqlInterpolated et des procédures stockées, tout en évitant les injections.
SQL brut, procédures stockées et interpolation est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.
Quand utiliser du SQL brut avec EF Core
La plupart des requêtes fonctionnent bien avec LINQ, mais certains scénarios nécessitent du SQL brut : analyses complexes, fonctions propres à un fournisseur, procédures stockées ou requêtes critiques pour les performances que LINQ traduit mal.
EF Core fournit des moyens sûrs d'utiliser du SQL brut sans compromettre la sécurité.
FromSqlRaw : requêtes paramétrées sécurisées
FromSqlRaw exécute du SQL brut et remappe les résultats vers des entités. Utilisez toujours des espaces réservés {0} — jamais de concaténation de chaînes — afin d'empêcher les injections SQL.
// SAFE: parameterized
var products = await _db.Products
.FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 100m)
.ToListAsync();
// DANGEROUS: never do this
// FromSqlRaw("SELECT * FROM Products WHERE Price > " + price)FromSqlInterpolated : sécurité des chaînes interpolées
FromSqlInterpolated accepte une chaîne interpolée C#. EF Core convertit automatiquement les valeurs interpolées en paramètres SQL : la solution est sûre et lisible.
decimal minPrice = 100m;
string category = "Electronics";
var products = await _db.Products
.FromSqlInterpolated(
$"SELECT * FROM Products WHERE Price > {minPrice} AND Category = {category}")
.OrderBy(p => p.Name)
.ToListAsync();
// Values become @p0, @p1 parameters automaticallyComposer du LINQ après FromSql
Vous pouvez enchaîner des opérateurs LINQ après FromSql. EF Core encapsule votre SQL brut dans une sous-requête, puis applique LINQ par-dessus, ce qui est utile pour ajouter un filtrage ou une pagination.
decimal min = 50m;
var page = await _db.Products
.FromSqlInterpolated($"SELECT * FROM Products WHERE Price > {min}")
.Where(p => p.IsActive) // additional LINQ filter
.OrderBy(p => p.Price)
.Skip(0).Take(20) // pagination
.ToListAsync();
// Generates: SELECT ... FROM (raw SQL) AS p WHERE ...Exécuter des procédures stockées
Appelez les procédures stockées qui renvoient des lignes d'entités avec FromSqlRaw. Pour les procédures qui ne renvoient aucune ligne (par exemple, INSERT/UPDATE), utilisez ExecuteSqlRawAsync.
// Stored proc returning Products
var products = await _db.Products
.FromSqlRaw("EXEC GetProductsByCategory {0}", "Books")
.ToListAsync();
// Stored proc with no return rows
await _db.Database.ExecuteSqlRawAsync(
"EXEC ArchiveOldOrders {0}",
DateTime.UtcNow.AddYears(-1));ExecuteSqlInterpolated pour le DML
ExecuteSqlInterpolated exécute des instructions DML (INSERT, UPDATE, DELETE) en assurant la sécurité des chaînes interpolées. Il renvoie le nombre de lignes affectées.
int days = 30;
int affected = await _db.Database.ExecuteSqlInterpolatedAsync(
$"UPDATE Orders SET Status = 'Expired' WHERE PlacedAt < {DateTime.UtcNow.AddDays(-days)}");
Console.WriteLine($"{affected} orders expired");Interroger des types qui ne sont pas des entités
Utilisez SqlQuery<T> (.NET 7+) pour interroger des types scalaires ou des DTO arbitraires qui ne sont pas des entités EF Core. Aucun DbSet n'est nécessaire.
// Query a DTO directly — no entity needed
var stats = await _db.Database
.SqlQuery<ProductStats>(
$"SELECT Category, COUNT(*) AS Count, AVG(Price) AS AvgPrice FROM Products GROUP BY Category")
.ToListAsync();
public record ProductStats(string Category, int Count, decimal AvgPrice);Types d'entités sans clé pour les vues
Mappez une vue de base de données ou le résultat d'une requête brute vers un type d'entité sans clé avec HasNoKey() et ToView(). Interrogez-le comme un DbSet sans avoir besoin d'une clé primaire.
public class ProductSalesSummary
{
public string Category { get; set; } = "";
public int TotalSold { get; set; }
public decimal Revenue { get; set; }
}
// In OnModelCreating:
modelBuilder.Entity<ProductSalesSummary>()
.HasNoKey()
.ToView("vw_ProductSalesSummary");
// Query:
var summary = await _db.Set<ProductSalesSummary>().ToListAsync();Éviter les pièges de l'injection SQL
La règle d'or : ne concaténez jamais des données saisies par l'utilisateur dans des chaînes SQL. Utilisez toujours des requêtes paramétrées via les espaces réservés de FromSqlRaw, FromSqlInterpolated ou le LINQ d'EF Core.
// SAFE
var name = userInput;
var result = await _db.Products
.FromSqlInterpolated($"SELECT * FROM Products WHERE Name = {name}")
.ToListAsync();
// INJECTION RISK (never do this)
// FromSqlRaw("SELECT * FROM Products WHERE Name = '" + name + "'");Paramètres de sortie avec solution de repli ADO.NET
EF Core ne prend pas nativement en charge les paramètres de sortie des procédures stockées. Dans ce cas, utilisez ADO.NET en passant par _db.Database.GetDbConnection().
await _db.Database.OpenConnectionAsync();
var conn = _db.Database.GetDbConnection();
using var cmd = conn.CreateCommand();
cmd.CommandText = "EXEC GetOrderCount @CustomerId, @Count OUTPUT";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@CustomerId", 5));
var outParam = new SqlParameter("@Count", SqlDbType.Int) { Direction = ParameterDirection.Output };
cmd.Parameters.Add(outParam);
await cmd.ExecuteNonQueryAsync();
int count = (int)outParam.Value;Cas concret : solution de repli pour la recherche en texte intégral
LINQ ne permet pas d'exprimer les prédicats de recherche en texte intégral propres à une base de données. Utilisez FromSqlInterpolated pour exploiter les fonctionnalités natives de FREETEXT ou de tsvector.
string query = "keyboard mechanical";
var results = await _db.Products
.FromSqlInterpolated(
$"SELECT * FROM Products WHERE FREETEXT(Name, {query})")
.AsNoTracking()
.Take(20)
.ToListAsync();Vérification rapide
Pourquoi FromSqlInterpolated est-il plus sûr que la concaténation de chaînes pour les requêtes paramétrées ?
Récapitulatif : SQL brut avec EF Core
Points essentiels :
FromSqlRaw: utilisez des espaces réservés {0} ; ne concaténez jamais les données saisies par l'utilisateurFromSqlInterpolated: chaînes interpolées sûres → paramètres ADO.NET- Enchaînez des opérateurs LINQ après FromSql pour ajouter un filtrage, un tri ou une pagination
ExecuteSqlInterpolatedAsync: exécution sûre du DMLSqlQuery<T>: interroger des DTO qui ne sont pas des entités (.NET 7+)- Utilisez directement ADO.NET pour les paramètres de sortie ou les procédures stockées complexes
Questions Fréquemment Posées
La leçon « SQL brut, procédures stockées et interpolation » est-elle gratuite ?
Oui — le texte complet de « SQL brut, procédures stockées et interpolation » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « SQL brut, procédures stockées et interpolation » ?
Exécutez du SQL brut en toute sécurité avec FromSqlRaw, FromSqlInterpolated et des procédures stockées, tout en évitant les injections. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C# Academy ?
Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « SQL brut, procédures stockées et interpolation » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?
Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Chargement immédiat, différé et explicite
- SQL brut, procédures stockées et interpolation
- Requêtes compilées et performances
- Filtres de requêtes globaux et entités possédées