Geçenlerde eski bir projemi elden geçirirken fark ettim ki, PostgreSQL ile yaptığım ilk bağlantı denemesinde yaşadığım o küçük heyecan hâlâ aynı 🙂 Hani ilk defa bir veritabanı sunucusuna bağlanıp “Connected” mesajını gördüğüm an vardı ya… İşte o an gözümün önüne geldi. Bu yazıda da C# ile PostgreSQL’e nasıl bağlanılır, Dapper ile nasıl temel CRUD işlemleri yapılır, biraz ondan bahsedeceğim. Ama öyle kuru kuru değil, yine benim tarzımda, biraz sohbet biraz kod, biraz da anı karışık bir şekilde 🙂
PostgreSQL, açık kaynaklı ve oldukça güçlü bir veritabanı sistemi. Özellikle karmaşık sorgular ve büyük veri setleriyle çalışırken performans açısından gayet başarılı. Benim gibi REST API geliştiren biri için de oldukça kullanışlı. Dapper ise, Entity Framework gibi ağır ORM’lerin aksine, hafif ve hızlı bir micro ORM. SQL yazmayı sevenler için birebir.
Bağlantı Kurulumu
İlk iş olarak, Npgsql NuGet paketini projeye dahil etmek gerekiyor. Npgsql, .NET uygulamalarının PostgreSQL ile konuşmasını sağlayan kütüphane. Ardından Dapper’ı da ekliyoruz. Bunları yaptıktan sonra, bağlantı stringimizi oluşturuyoruz. Örnek bir bağlantı string şöyle olabilir:
"Host=localhost;Port=5432;Username=postgres;Password=1234;Database=deneme_db"
Tabi burada şifreyi düz yazmak pek hoş değil ama örnek diye böyle yazdım 🙂 Gerçek projelerde konfigürasyon dosyalarında saklamak daha mantıklı. Neyse efendim, bağlantıyı kurduktan sonra artık sorgulara geçebiliriz.
CRUD İşlemleri
Dapper ile çalışmak oldukça basit. Mesela bir kullanıcıyı listelemek için şöyle bir kod yazılır:
using (var connection = new NpgsqlConnection(connString))
{
var users = connection.Query<User>("SELECT * FROM users").ToList();
}
Burada User sınıfı, veritabanındaki users tablosuna karşılık gelen model. Sütun adları birebir eşleşmeli, yoksa eşleştirme yapmaz. Bu arada, Dapper’ın bu kadar hızlı olmasının sebebi de zaten bu sadelik.
Insert işlemi de oldukça kolay. Şöyle bir örnek:
var sql = "INSERT INTO users (name, email) VALUES (@Name, @Email)";
connection.Execute(sql, new { Name = "Ali", Email = "ali@example.com" });
Update ve Delete işlemleri de aynı mantıkla gidiyor. SQL yazıyorsun, Dapper parametreleri eşliyor, işlem tamam. Hızlı, sade ve anlaşılır.
Geçen hafta kamp alanında, akşam çadırı kurduktan sonra bir şeyler karalamak istedim. Yanımda laptop vardı ama internet yoktu. Offline bir şeyler deneyeyim dedim. Dapper ile yazdığım örnek bir proje vardı. PostgreSQL’i docker ile lokal çalıştırıyordum. Her şey güzel gidiyordu derken, bir türlü bağlantı kuramıyorum. Bağlantı dizesi doğru, port açık, docker çalışıyor ama yok, bağlantı kurulmuyor.
Meğer docker’da PostgreSQL konteynerini başlatırken volume mount etmeyi unutmuşum. Veritabanı her restart’ta sıfırlanıyordu 🙂 O an fark ettim ki, bazen en basit şeyi unutup saatlerce başka yerde hata arıyoruz. Kamp alanında gece el feneriyle log dosyası okumaya çalıştım, o da ayrı bir macera 🙂
Dapper’ın Avantajları
Şimdi şöyle bir şey var; Entity Framework gibi büyük ORM’ler her ne kadar çok şey sunsa da, bazen fazla geliyor. Dapper ise tam tersi. Ne verirsen onu yapıyor. SQL yazmayı seven biriysen, Dapper tam sana göre. Performanslı, sade ve kontrol sende. Tabi join’li karmaşık sorgularda dikkatli olmak lazım, mapping işini sen yapıyorsun çünkü.
Benim deneyimime göre, küçük ve orta ölçekli projelerde Dapper gayet yeterli. Özellikle REST API geliştirirken çok işime yarıyor. Hatta bazen sadece okuma işlemleri için bile Dapper kullanmak mantıklı.
Ufak Bir Not
Bu arada, Dapper ile çalışırken dikkat edilmesi gereken bir şey de şu: Eğer sorgularında dinamik alanlar varsa (mesela tablo adı, sütun adı vs.), bunları parametre ile veremezsin. Yani parametre sadece değerler için geçerli. SQL injection’a dikkat etmek lazım. Bunu unutursan, başına iş alırsın.
Bir de, bazı durumlarda async metodları kullanmak gerekiyor. Örneğin:
var users = await connection.QueryAsync<User>("SELECT * FROM users");
Bu şekilde yazarsan, performans açısından daha iyi olur. Tabi await/async yapısını doğru kullanmak gerekiyor, yoksa kodun içinden çıkamazsın 🙂
Bu arada aklıma geldi, geçenlerde bir arkadaş “Dapper çok hızlı ama transaction destekliyor mu?” diye sordu. Evet, destekliyor. Hatta transaction ile çalışmak da oldukça basit. connection.BeginTransaction() ile başlatıp, işlemleri yapıp commit ediyorsun. Hepsi bu kadar.
Son Söz
Açıkçası ben Dapper’ı seviyorum. Hem hafif, hem hızlı. PostgreSQL ile de gayet güzel çalışıyor. Tabi her projeye uygun mu? Değil. Ama çoğu zaman işini fazlasıyla görüyor. Neticede, her zaman en karmaşık araç en iyisi değildir. Bazen basit olan daha etkili olur.
Sen ne dersin? Dapper kullandın mı hiç? Eğer denemediysen, küçük bir proje ile başla derim. Zaten bir kere alışınca bırakması zor oluyor 🙂