Rohes SQL, Stored Procedures und Interpolation
Führen Sie rohes SQL sicher mit FromSqlRaw, FromSqlInterpolated und Stored Procedures aus und vermeiden Sie dabei Injection-Angriffe.
Rohes SQL, Stored Procedures und Interpolation ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Wann Sie Raw SQL in EF Core verwenden sollten
Die meisten Abfragen funktionieren mit LINQ problemlos, aber einige Szenarien erfordern Raw SQL: komplexe Analysen, anbieterspezifische Funktionen, gespeicherte Prozeduren oder performanzkritische Abfragen, die LINQ nur schlecht übersetzt.
EF Core bietet sichere Möglichkeiten zur Verwendung von Raw SQL, ohne die Sicherheit zu beeinträchtigen.
Sichere parametrisierte Abfragen mit FromSqlRaw
FromSqlRaw führt Raw SQL aus und ordnet die Ergebnisse wieder Entitäten zu. Verwenden Sie immer Platzhalter wie {0} – niemals Stringverkettung –, um SQL-Injection zu verhindern.
// 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)Sicherheit durch interpolierte Zeichenfolgen mit FromSqlInterpolated
FromSqlInterpolated akzeptiert eine interpolierte C#-Zeichenfolge. EF Core wandelt die interpolierten Werte automatisch in SQL-Parameter um – sicher und gut lesbar.
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 automaticallyLINQ nach FromSql zusammenstellen
Sie können LINQ-Operatoren an FromSql anhängen. EF Core kapselt Ihr Raw SQL als Unterabfrage und wendet LINQ darauf an. Das ist nützlich, um Filter oder Seitennummerierung hinzuzufügen.
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 ...Gespeicherte Prozeduren ausführen
Rufen Sie gespeicherte Prozeduren, die Entitätszeilen zurückgeben, über FromSqlRaw auf. Verwenden Sie für Prozeduren, die keine Zeilen zurückgeben (z. B. 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 für DML
ExecuteSqlInterpolated führt DML-Anweisungen (INSERT, UPDATE, DELETE) mit der Sicherheit interpolierter Zeichenfolgen aus. Die Methode gibt die Anzahl der betroffenen Zeilen zurück.
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");Nicht-Entitätstypen abfragen
Verwenden Sie SqlQuery<T> (.NET 7+), um beliebige skalare Typen oder DTOs abzufragen, die keine EF-Core-Entitäten sind. Ein DbSet ist nicht erforderlich.
// 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);Schlüssellose Entitätstypen für Views
Ordnen Sie eine Datenbank-View oder das Ergebnis einer Raw-Abfrage mit HasNoKey() und ToView() einem schlüssellosen Entitätstyp zu. Fragen Sie ihn wie ein DbSet ab, ohne dass ein Primärschlüssel erforderlich ist.
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();Fallstricke bei SQL-Injection vermeiden
Die goldene Regel: Verketten Sie niemals Benutzereingaben mit SQL-Zeichenfolgen. Verwenden Sie immer parametrisierte Abfragen über FromSqlRaw-Platzhalter, FromSqlInterpolated oder EF Cores LINQ.
// 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 + "'");Ausgabeparameter mit ADO.NET-Fallback
EF Core unterstützt Ausgabeparameter von gespeicherten Prozeduren nicht nativ. Weichen Sie in diesen Fällen auf ADO.NET aus und verwenden Sie _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;Praxisbeispiel: Fallback für die Volltextsuche
LINQ kann datenbankspezifische Prädikate für die Volltextsuche nicht ausdrücken. Verwenden Sie FromSqlInterpolated, um die nativen Funktionen FREETEXT oder tsvector zu nutzen.
string query = "keyboard mechanical";
var results = await _db.Products
.FromSqlInterpolated(
$"SELECT * FROM Products WHERE FREETEXT(Name, {query})")
.AsNoTracking()
.Take(20)
.ToListAsync();Kurzer Check
Warum ist FromSqlInterpolated bei parametrisierten Abfragen sicherer als Stringverkettung?
Zusammenfassung: Raw SQL in EF Core
Wichtigste Erkenntnisse:
FromSqlRaw: Verwenden Sie {0}-Platzhalter; verketten Sie niemals BenutzereingabenFromSqlInterpolated: sichere interpolierte Zeichenfolgen → ADO.NET-Parameter- Verketten Sie nach FromSql LINQ-Operatoren, um Filter, Sortierung und Seitennummerierung hinzuzufügen
ExecuteSqlInterpolatedAsync: sichere DML-AusführungSqlQuery<T>: Nicht-Entitäts-DTOs abfragen (.NET 7+)- Verwenden Sie ADO.NET direkt für Ausgabeparameter oder komplexe gespeicherte Prozeduren
Häufig gestellte Fragen
Ist die Lektion „Rohes SQL, Stored Procedures und Interpolation“ kostenlos?
Ja — der vollständige Text von „Rohes SQL, Stored Procedures und Interpolation“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Rohes SQL, Stored Procedures und Interpolation“?
Führen Sie rohes SQL sicher mit FromSqlRaw, FromSqlInterpolated und Stored Procedures aus und vermeiden Sie dabei Injection-Angriffe. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Rohes SQL, Stored Procedures und Interpolation“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Eager-, Lazy- und Explicit-Loading
- Rohes SQL, Stored Procedures und Interpolation
- Kompilierte Abfragen und Performance
- Globale Abfragefilter und Owned Entities