C# Academy · Les

Raw SQL, stored procedures en interpolatie

Voer veilig raw SQL uit met FromSqlRaw, FromSqlInterpolated en stored procedures, en voorkom injectie.

Les 2 van 413 stappen

Raw SQL, stored procedures en interpolatie is een gratis C# Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject C# Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus C# Academy bevat in totaal 4 lessen.

Wanneer gebruik je onbewerkte SQL in EF Core

De meeste queries werken prima met LINQ, maar sommige scenario's vereisen onbewerkte SQL: complexe analyses, leveranciersspecifieke functies, opgeslagen procedures of prestatiekritieke queries die LINQ slecht vertaalt.

EF Core biedt veilige manieren om onbewerkte SQL te gebruiken zonder aan beveiliging in te boeten.

FromSqlRaw: veilige geparametriseerde queries

FromSqlRaw voert onbewerkte SQL uit en koppelt de resultaten terug aan entiteiten. Gebruik altijd {0}-plaatsaanduidingen — nooit tekenreekssamenvoeging — om SQL-injectie te voorkomen.

// 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: veiligheid met interpolatie

FromSqlInterpolated accepteert een geïnterpoleerde C#-tekenreeks. EF Core zet de geïnterpoleerde waarden automatisch om in SQL-parameters — veilig en leesbaar.

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 automatically

LINQ samenstellen na FromSql

Je kunt LINQ-operatoren koppelen na FromSql. EF Core verpakt je onbewerkte SQL als een subquery en past daar LINQ op toe. Dat is handig om filteren of paginering toe te voegen.

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 ...

Opgeslagen procedures uitvoeren

Roep opgeslagen procedures die entiteitsrijen retourneren aan via FromSqlRaw. Gebruik voor procedures die geen rijen retourneren (bijvoorbeeld INSERT/UPDATE) 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 voor DML

ExecuteSqlInterpolated voert DML-instructies (INSERT, UPDATE, DELETE) uit met de veiligheid van geïnterpoleerde tekenreeksen. De methode retourneert het aantal gewijzigde rijen.

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");

Typen zonder entiteiten opvragen

Gebruik SqlQuery<T> (.NET 7+) om willekeurige scalaire typen of DTO's op te vragen die geen EF Core-entiteiten zijn. Een DbSet is niet nodig.

// 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);

Entiteitstypen zonder sleutel voor weergaven

Koppel een databaseweergave of het resultaat van een onbewerkte query aan een entiteitstype zonder sleutel met HasNoKey() en ToView(). Je kunt erop query'en zoals op een DbSet, zonder een primaire sleutel nodig te hebben.

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();

Valkuilen bij het voorkomen van SQL-injectie

De gulden regel: voeg gebruikersinvoer nooit samen in SQL-tekenreeksen. Gebruik altijd geparametriseerde queries via FromSqlRaw-plaatsaanduidingen, FromSqlInterpolated of LINQ van 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 + "'");

Uitvoerparameters met ADO.NET als terugvaloptie

EF Core biedt geen ingebouwde ondersteuning voor uitvoerparameters van opgeslagen procedures. Val in die gevallen terug op ADO.NET met _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;

Praktijkvoorbeeld: terugvaloptie voor zoeken in volledige tekst

Met LINQ kun je geen databasespecifieke predicaten voor zoeken in volledige tekst uitdrukken. Gebruik FromSqlInterpolated om de systeemeigen mogelijkheden van FREETEXT of tsvector te benutten.

string query = "keyboard mechanical";
var results = await _db.Products
    .FromSqlInterpolated(
        $"SELECT * FROM Products WHERE FREETEXT(Name, {query})")
    .AsNoTracking()
    .Take(20)
    .ToListAsync();

Korte controle

Waarom is FromSqlInterpolated veiliger dan tekenreekssamenvoeging voor geparametriseerde queries?

Samenvatting: onbewerkte SQL in EF Core

Belangrijkste punten:

  • FromSqlRaw: gebruik {0}-plaatsaanduidingen; voeg gebruikersinvoer nooit samen
  • FromSqlInterpolated: veilige geïnterpoleerde tekenreeksen → ADO.NET-parameters
  • Koppel LINQ-operatoren na FromSql om te filteren, sorteren en pagineren
  • ExecuteSqlInterpolatedAsync: veilige uitvoering van DML
  • SqlQuery<T>: vraag DTO's zonder entiteit op (.NET 7+)
  • Gebruik ADO.NET rechtstreeks voor uitvoerparameters of complexe opgeslagen procedures
Gratis beginnen

Leer C# met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
93
Lessen
346

Veelgestelde vragen

Is de les “Raw SQL, stored procedures en interpolatie” gratis?

Ja — de volledige tekst van “Raw SQL, stored procedures en interpolatie” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus C# Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus C# Academy bevat in totaal 4 lessen.

Wat leer ik in “Raw SQL, stored procedures en interpolatie”?

Voer veilig raw SQL uit met FromSqlRaw, FromSqlInterpolated en stored procedures, en voorkom injectie. Je oefent met C# Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met C# Academy te beginnen?

Ervaring vooraf is niet nodig. C# Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “Raw SQL, stored procedures en interpolatie”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over C# Academy?

Ja. Elke les over C# Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Eager, lazy en explicit loading
  2. Raw SQL, stored procedures en interpolatie
  3. Gecompileerde query's en prestaties
  4. Globale queryfilters en owned entities
← Terug naar C# Academy