Gereksinimler ve Ön Hazırlık
Dapper kullanmaya başlamadan önce, projenizin gereksinimlerini karşıladığından emin olmalısınız. Dapper, .NET 6, 7, 8 ve 2026 itibarıyla güncel olan .NET 9+ sürümleriyle tam uyumludur.
- Visual Studio 2022 veya güncel VS Code kurulumu.
- .NET SDK (projenizin hedef sürümü).
- SQL Server, PostgreSQL veya MySQL gibi bir veri tabanı yönetim sistemi.
- Projenize eklenmiş Dapper ve veri tabanı sürücüsü (örneğin SQL Server için Microsoft.Data.SqlClient) NuGet paketleri.
Paketleri yüklemek için terminalinizde şu komutu çalıştırabilirsiniz:
dotnet add package Dapper
dotnet add package Microsoft.Data.SqlClient
Bu komutlar, projenize Dapper kütüphanesini ve SQL Server ile haberleşmenizi sağlayacak olan sürücüyü ekleyecektir.
Dapper ile Veri Tabanına Bağlanma ve Sorgulama
Dapper, standart IDbConnection arayüzü üzerinden çalışır. Bu, herhangi bir ADO.NET uyumlu veri tabanı sağlayıcısı ile çalışabileceğiniz anlamına gelir. İlk adımımız, bir bağlantı oluşturmak ve basit bir sorgu çalıştırmaktır.
using Microsoft.Data.SqlClient;
using Dapper;
string connectionString = "Server=localhost;Database=UygulamaDB;Trusted_Connection=True;";
using (var connection = new SqlConnection(connectionString))
{
string sql = "SELECT Id, Ad, Soyad FROM Kullanicilar";
var kullanicilar = connection.Query(sql).ToList();
foreach (var k in kullanicilar)
{
Console.WriteLine($"{k.Ad} {k.Soyad}");
}
}
Yukarıdaki kod bloğunda, connection.Query metodunu kullanarak SQL sonucunu doğrudan Kullanici nesnelerine dönüştürdük. Dapper, sütun isimleri ile sınıf özelliklerini otomatik olarak eşleştirir.
Parametreli Sorgularla SQL Injection Koruması
Veri tabanı işlemlerinde en büyük güvenlik riski SQL Injection saldırılarıdır. Kullanıcıdan alınan verileri doğrudan SQL sorgusuna eklemek yerine mutlaka parametre kullanmalısınız. Dapper, anonim nesneler aracılığıyla güvenli parametre kullanımını kolaylaştırır.
string sql = "SELECT * FROM Kullanicilar WHERE Id = @Id";
int kullaniciId = 5;
var kullanici = connection.QueryFirstOrDefault(sql, new { Id = kullaniciId });
if (kullanici != null)
{
Console.WriteLine($"Bulunan Kullanıcı: {kullanici.Ad}");
}
Burada @Id parametresi, Dapper tarafından güvenli bir şekilde işlenir. Bu sayede kötü niyetli SQL komutlarının çalıştırılması engellenmiş olur.
Kritik Uyarı: Asla kullanıcıdan gelen verileri string birleştirme (string interpolation) yöntemiyle doğrudan SQL sorgularına dahil etmeyin. Her zaman Dapper'ın sunduğu anonim nesne parametrelerini kullanın.
Veri Ekleme, Güncelleme ve Silme (CRUD)
Dapper ile veri tabanına veri yazmak, okumak kadar kolaydır. Execute metodu, geriye bir veri döndürmeyen (INSERT, UPDATE, DELETE) işlemler için kullanılır.
// Veri Ekleme
string insertSql = "INSERT INTO Kullanicilar (Ad, Soyad) VALUES (@Ad, @Soyad)";
var yeniKullanici = new { Ad = "Ahmet", Soyad = "Yılmaz" };
connection.Execute(insertSql, yeniKullanici);
// Veri Güncelleme
string updateSql = "UPDATE Kullanicilar SET Soyad = @Soyad WHERE Id = @Id";
connection.Execute(updateSql, new { Soyad = "Demir", Id = 1 });
// Veri Silme
string deleteSql = "DELETE FROM Kullanicilar WHERE Id = @Id";
connection.Execute(deleteSql, new { Id = 1 });
Execute metodu, işlem sonucunda etkilenen satır sayısını bir int değeri olarak döndürür. Bu değeri kontrol ederek işlemin başarılı olup olmadığını doğrulayabilirsiniz.
Dapper vs Entity Framework: Hangisini Seçmeli?
Yazılım projelerinde doğru araç seçimi, performans ve geliştirme süresi dengesini belirler. Aşağıdaki tablo, Dapper ve Entity Framework (EF) arasındaki temel farkları özetlemektedir.
| Özellik | Dapper | Entity Framework |
|---|---|---|
| Performans | Çok Yüksek (Native SQL hızı) | Orta (Ek yükler içerir) |
| Öğrenme Eğrisi | Düşük (SQL bilgisi yeterli) | Yüksek (ORM kuralları) |
| SQL Kontrolü | Tam kontrol | Kısıtlı (LINQ to SQL) |
| Otomasyon | Düşük (Manuel sorgu yazımı) | Yüksek (Migration, Change Tracking) |
İleri Seviye: İşlemler (Transactions) ve Çoklu Sorgular
Bazen birden fazla veri tabanı işleminin tek bir birim olarak gerçekleşmesi gerekir. Eğer bir işlem başarısız olursa, diğerlerinin de geri alınması (rollback) gerekir. Dapper ile ADO.NET Transaction yapısını kolayca kullanabilirsiniz.
using (var transaction = connection.BeginTransaction())
{
try
{
connection.Execute("UPDATE Hesaplar SET Bakiye = Bakiye - 100 WHERE Id = 1", transaction: transaction);
connection.Execute("UPDATE Hesaplar SET Bakiye = Bakiye + 100 WHERE Id = 2", transaction: transaction);
transaction.Commit();
}
catch
{
transaction.Rollback();
}
}
Bu örnekte, iki farklı güncelleme işlemini bir işlem bloğuna aldık. Eğer herhangi bir hata oluşursa, catch bloğu sayesinde veri tabanı tutarlılığını korumuş olduk.
Sıkça Sorulan Sorular
Dapper ile asenkron işlemler nasıl yapılır?
Dapper, QueryAsync ve ExecuteAsync metotları ile tam asenkron desteği sunar. Veri tabanı işlemlerini beklerken uygulamanızın kilitlenmemesi için bu metotları tercih etmelisiniz.
Dapper'da "Stored Procedure" nasıl çağrılır?
commandType: CommandType.StoredProcedure parametresini kullanarak kolayca çağırabilirsiniz. Dapper, parametreleri otomatik olarak prosedür parametreleriyle eşleştirir.
Dapper'da karmaşık nesne eşleme mümkün mü?
Evet, Query yapısını kullanarak "Multi-Mapping" özelliği ile ilişkili tabloları (Join işlemleri) tek bir sorguda nesneleştirebilirsiniz.
Dapper'ın nesne eşleme hızı neden bu kadar yüksek?
Dapper, çalışma zamanında (runtime) IL (Intermediate Language) kodları oluşturarak veri okuma işlemini optimize eder. Bu, yansıma (reflection) kullanımının maliyetini neredeyse sıfıra indirir.
Dapper'ı hangi projelerde kullanmalıyım?
Yüksek trafikli mikroservisler, performansın kritik olduğu raporlama sistemleri ve SQL sorguları üzerinde tam hakimiyet istediğiniz her projede Dapper mükemmel bir tercihtir.
Güvenlik Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında veri tabanı bağlantı dizelerinizi (connection strings) asla kod içerisinde açık bırakmayın; bunun yerine "User Secrets" veya "Azure Key Vault" gibi güvenli yapılandırma yönetim araçlarını kullanın.
Dapper Projelerinde Hata Ayıklama ve Performans İzleme
Dapper, SQL sorgularını doğrudan çalıştırdığı için hata ayıklama süreci, Entity Framework gibi ORM araçlarından biraz daha farklıdır. Sorgularınızın çalışma zamanında nasıl göründüğünü ve veri tabanında ne kadar süre harcadığını anlamak, ölçeklenebilir uygulamalar için kritiktir.
SQL Profiling ile Sorgu Analizi
Sorgularınızın performansını ölçmek için MiniProfiler gibi araçlar kullanabilirsiniz. Bu araç, Dapper üzerinden gönderilen her bir SQL komutunun süresini ve parametre değerlerini tarayıcınızda veya log dosyalarınızda görmenizi sağlar. Aşağıdaki örnek, bir sorgunun çalışma süresini manuel olarak izlemek için basit bir yöntem sunar:
using System.Diagnostics;
public async Task GetProductsWithLogging(IDbConnection db)
{
var watch = Stopwatch.StartNew();
var sql = "SELECT * FROM Products WHERE CategoryId = @Id";
var result = (await db.QueryAsync(sql, new { Id = 1 })).ToList();
watch.Stop();
Console.WriteLine($"Sorgu süresi: {watch.ElapsedMilliseconds} ms");
return result;
}
Yaygın Hata Senaryoları ve Çözümleri
Dapper kullanırken karşılaşılan en yaygın hatalar genellikle tip uyuşmazlıkları ve yanlış parametre eşlemeleridir. İşte dikkat etmeniz gereken noktalar:
- Null Değerler: C# tarafında
nullolan bir değişkeni SQL'e gönderirkenDBNull.Valuekontrolü yapmanız gerekebilir. Dapper genellikle bunu otomatik yönetse de, karmaşık tiplerde hata alabilirsiniz. - Mapping Hataları: SQL sorgusundaki sütun isimleri ile C# nesnenizin property isimleri birebir eşleşmelidir. Eğer isimler farklıysa
ASanahtar kelimesini SQL tarafında kullanmayı unutmayın. - Bağlantı Sızıntıları:
IDbConnectionnesnesini her zamanusingbloğu içerisinde kullanarak bağlantının işlem bitiminde kapatıldığından emin olun.
Dapper ile Birim Testi (Unit Testing) Stratejileri
Dapper doğrudan veri tabanı ile konuştuğu için, birim testleri yazarken gerçek bir veri tabanına bağlanmak yerine "Mocking" kütüphaneleri veya "In-Memory" veri tabanları kullanmak en iyi pratiktir. Moq kütüphanesi ile IDbConnection arayüzünü taklit ederek, veri tabanı bağımlılığı olmadan kodunuzu test edebilirsiniz.
// Örnek bir Moq senaryosu
var mockConnection = new Mock();
var mockData = new List { new Product { Id = 1, Name = "Test Ürün" } };
// Dapper'ın Query metodunu taklit etme
mockConnection.Setup(m => m.Query(It.IsAny(), null, null, true, null, null))
.Returns(mockData);
// Artık bu mockConnection nesnesini servis katmanınıza enjekte edebilirsiniz.
Bu yaklaşım, testlerinizin hızlı çalışmasını sağlar ve veri tabanı sunucusuna olan bağımlılığı ortadan kaldırarak CI/CD süreçlerinizi hızlandırır. Test aşamasında SQLite In-Memory veri tabanını kullanarak, gerçek SQL sorgularınızın doğruluğunu da kontrol edebilirsiniz.
Sonuç
C# ile Dapper kullanmak, veri tabanı işlemlerinde hem hız hem de esneklik kazanmanızı sağlar. SQL sorgularınız üzerinde tam denetim sahibi olurken, ADO.NET'in karmaşıklığından kurtulup temiz ve okunabilir kodlar yazabilirsiniz. Bu rehberde öğrendiğiniz temel CRUD işlemleri, parametreli sorgular ve transaction yönetimi, profesyonel bir yazılım geliştiricinin ihtiyaç duyacağı temel yetkinliklerdir.
Bir sonraki adım olarak, Dapper ile Dapper.Contrib kütüphanesini inceleyerek CRUD işlemlerini daha da otomatize etmeyi deneyebilir veya "Multi-Mapping" teknikleri ile karmaşık veri ilişkilerini nasıl yöneteceğinizi pratik edebilirsiniz.


Yorumlar (0)
Yorum Yaz