0Pricing
C# Academy · Ders

Ham SQL, Saklı Yordamlar ve Enterpolasyon

FromSqlRaw, FromSqlInterpolated ve saklı yordamlarla ham SQL'i güvenle çalıştırırken enjeksiyondan kaçının.

Ham SQL, Saklı Yordamlar ve Enterpolasyon, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.

EF Core'da Ham SQL Ne Zaman Kullanılmalı

Çoğu sorgu LINQ ile sorunsuz çalışır, ancak bazı senaryolarda ham SQL gerekir: karmaşık analizler, sağlayıcıya özgü işlevler, saklı yordamlar veya LINQ tarafından kötü çevrilen performans açısından kritik sorgular.

EF Core, güvenlikten ödün vermeden ham SQL kullanmanız için güvenli yollar sağlar.

FromSqlRaw: Güvenli Parametreli Sorgular

FromSqlRaw ham SQL'i çalıştırır ve sonuçları yeniden varlıklara eşler. SQL enjeksiyonunu önlemek için her zaman {0} yer tutucularını kullanın — asla dize birleştirme kullanmayın.

// 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: Dize İnterpolasyonuyla Güvenlik

FromSqlInterpolated bir C# dize interpolasyonunu kabul eder. EF Core, interpolasyonla oluşturulan değerleri otomatik olarak SQL parametrelerine dönüştürür; bu yöntem hem güvenli hem de okunabilirdir.

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

FromSql Sonrasında LINQ Sorguları Oluşturma

FromSql sonrasında LINQ işleçlerini zincirleyebilirsiniz. EF Core, ham SQL'inizi bir alt sorgu olarak sarar ve üzerine LINQ uygular; bu, filtreleme veya sayfalama eklemek için kullanışlıdır.

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

Saklı Yordamları Çalıştırma

Varlık satırları döndüren saklı yordamları FromSqlRaw aracılığıyla çağırın. Satır döndürmeyen yordamlar için (ör. INSERT/UPDATE) ExecuteSqlRawAsync kullanın.

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

DML için ExecuteSqlInterpolated

ExecuteSqlInterpolated, DML ifadelerini (INSERT, UPDATE, DELETE) dize interpolasyonu güvenliğiyle çalıştırır. Etkilenen satır sayısını döndürür.

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

Varlık Olmayan Türleri Sorgulama

EF Core varlığı olmayan rastgele skaler veya veri aktarım nesnesi türlerini sorgulamak için SqlQuery<T> (.NET 7+) kullanın. DbSet gerekmez.

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

Görünümler için Anahtarsız Varlık Türleri

Bir veritabanı görünümünü veya ham sorgu sonucunu HasNoKey() ve ToView() kullanarak anahtarsız varlık türüne eşleyin. Birincil anahtar gerektirmeden bu türü DbSet gibi sorgulayın.

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

SQL Enjeksiyonu Tuzaklarından Kaçınma

Altın kural şudur: kullanıcı girdisini SQL dizelerine asla birleştirmeyin. Her zaman FromSqlRaw yer tutucuları, FromSqlInterpolated veya EF Core'un LINQ'i aracılığıyla parametreli sorgular kullanın.

// 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 + "'");

ADO.NET Geri Dönüşüyle Çıktı Parametreleri

EF Core, saklı yordamların çıktı parametrelerini yerel olarak desteklemez. Bu durumlarda _db.Database.GetDbConnection() kullanarak ADO.NET'e geri dönün.

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;

Gerçek Dünya: Tam Metin Araması için Geri Dönüş

LINQ, veritabanına özgü tam metin araması koşullarını ifade edemez. Yerel FREETEXT veya tsvector yeteneklerinden yararlanmak için FromSqlInterpolated kullanın.

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

Hızlı Kontrol

Parametreli sorgularda FromSqlInterpolated, dize birleştirmeye göre neden daha güvenlidir?

Özet: EF Core'da Ham SQL

Temel çıkarımlar:

  • FromSqlRaw: {0} yer tutucularını kullanın; kullanıcı girdisini asla birleştirmeyin
  • FromSqlInterpolated: güvenli dize interpolasyonları → ADO.NET parametreleri
  • Filtreleme, sıralama ve sayfalama eklemek için FromSql sonrasında LINQ işleçlerini zincirleyin
  • ExecuteSqlInterpolatedAsync: güvenli DML yürütme
  • SqlQuery<T>: varlık olmayan veri aktarım nesnelerini sorgulama (.NET 7+)
  • Çıktı parametreleri veya karmaşık saklı yordamlar için doğrudan ADO.NET kullanın

Sıkça Sorulan Sorular

“Ham SQL, Saklı Yordamlar ve Enterpolasyon” dersi ücretsiz mi?

Evet — “Ham SQL, Saklı Yordamlar ve Enterpolasyon” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.

“Ham SQL, Saklı Yordamlar ve Enterpolasyon” dersinde ne öğreneceğim?

FromSqlRaw, FromSqlInterpolated ve saklı yordamlarla ham SQL'i güvenle çalıştırırken enjeksiyondan kaçının. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C# Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Ham SQL, Saklı Yordamlar ve Enterpolasyon” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Hevesli, Tembel ve Açık Yükleme
  2. Ham SQL, Saklı Yordamlar ve Enterpolasyon
  3. Derlenmiş Sorgular ve Performans
  4. Genel Sorgu Filtreleri ve Sahipli Varlıklar
← C# Academy Sayfasına Dön