SQL Mentah, Prosedur Tersimpan & Interpolasi
Jalankan SQL mentah dengan aman menggunakan FromSqlRaw, FromSqlInterpolated, dan prosedur tersimpan sambil menghindari injeksi.
SQL Mentah, Prosedur Tersimpan & Interpolasi adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.
Kapan Menggunakan SQL Mentah di EF Core
Sebagian besar kueri dapat ditangani dengan baik oleh LINQ, tetapi beberapa skenario memerlukan SQL mentah: analitik kompleks, fungsi khusus penyedia basis data, prosedur tersimpan, atau kueri yang sangat mementingkan kinerja dan diterjemahkan dengan buruk oleh LINQ.
EF Core menyediakan cara yang aman untuk menggunakan SQL mentah tanpa mengorbankan keamanan.
FromSqlRaw: Kueri Berparameter yang Aman
FromSqlRaw menjalankan SQL mentah dan memetakan hasilnya kembali ke entitas. Selalu gunakan placeholder {0} — jangan pernah menggabungkan string — untuk mencegah injeksi 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: Keamanan String Terinterpolasi
FromSqlInterpolated menerima string C# terinterpolasi. EF Core secara otomatis mengonversi nilai yang terinterpolasi menjadi parameter SQL — aman dan mudah dibaca.
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 automaticallyMenyusun LINQ Setelah FromSql
Anda dapat merangkai operator LINQ setelah FromSql. EF Core membungkus SQL mentah Anda sebagai subkueri dan menerapkan LINQ di atasnya, yang berguna untuk menambahkan pemfilteran atau pembagian halaman.
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 ...Menjalankan Prosedur Tersimpan
Panggil prosedur tersimpan yang mengembalikan baris entitas melalui FromSqlRaw. Untuk prosedur yang tidak mengembalikan baris (misalnya, INSERT/UPDATE), gunakan 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 untuk DML
ExecuteSqlInterpolated menjalankan pernyataan DML (INSERT, UPDATE, DELETE) dengan keamanan string terinterpolasi. Fungsi ini mengembalikan jumlah baris yang terpengaruh.
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");Membuat Kueri untuk Jenis Non-Entitas
Gunakan SqlQuery<T> (.NET 7+) untuk membuat kueri atas jenis skalar atau DTO sembarang yang bukan entitas EF Core. Tidak diperlukan DbSet.
// 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);Jenis Entitas Tanpa Kunci untuk Tampilan
Petakan tampilan basis data atau hasil kueri mentah ke jenis entitas tanpa kunci menggunakan HasNoKey() dan ToView(). Buat kueri terhadapnya seperti pada DbSet tanpa memerlukan kunci utama.
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();Menghindari Jebakan Injeksi SQL
Aturan utamanya: jangan pernah menggabungkan masukan pengguna ke dalam string SQL. Selalu gunakan kueri berparameter melalui placeholder FromSqlRaw, FromSqlInterpolated, atau LINQ 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 + "'");Parameter Keluaran dengan Pengalihan ke ADO.NET
EF Core tidak mendukung parameter keluaran prosedur tersimpan secara bawaan. Untuk kasus tersebut, beralihlah ke ADO.NET menggunakan _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;Dunia Nyata: Pengalihan Pencarian Teks Lengkap
LINQ tidak dapat mengekspresikan predikat pencarian teks lengkap yang khusus untuk basis data. Gunakan FromSqlInterpolated untuk memanfaatkan kemampuan bawaan FREETEXT atau vektor teks.
string query = "keyboard mechanical";
var results = await _db.Products
.FromSqlInterpolated(
$"SELECT * FROM Products WHERE FREETEXT(Name, {query})")
.AsNoTracking()
.Take(20)
.ToListAsync();Pemeriksaan Singkat
Mengapa FromSqlInterpolated lebih aman daripada penggabungan string untuk kueri berparameter?
Ringkasan: SQL Mentah di EF Core
Hal-hal penting:
FromSqlRaw: gunakan placeholder {0}; jangan pernah menggabungkan masukan penggunaFromSqlInterpolated: string terinterpolasi yang aman → parameter ADO.NET- Rangkai operator LINQ setelah FromSql untuk menambahkan pemfilteran, pengurutan, dan pembagian halaman
ExecuteSqlInterpolatedAsync: eksekusi DML yang amanSqlQuery<T>: membuat kueri atas DTO non-entitas (.NET 7+)- Gunakan ADO.NET secara langsung untuk parameter keluaran atau prosedur tersimpan yang kompleks
Pertanyaan yang Sering Diajukan
Apakah pelajaran “SQL Mentah, Prosedur Tersimpan & Interpolasi” gratis?
Ya — teks lengkap “SQL Mentah, Prosedur Tersimpan & Interpolasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “SQL Mentah, Prosedur Tersimpan & Interpolasi”?
Jalankan SQL mentah dengan aman menggunakan FromSqlRaw, FromSqlInterpolated, dan prosedur tersimpan sambil menghindari injeksi. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C# Academy?
Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “SQL Mentah, Prosedur Tersimpan & Interpolasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?
Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pemuatan Eager, Lazy & Eksplisit
- SQL Mentah, Prosedur Tersimpan & Interpolasi
- Kueri Terkompilasi & Performa
- Filter Kueri Global & Entitas Owned