İçeriğe geç

C# .NET ile MySQL Entegrasyonu: Dapper Kullanarak Pratik Veri İşlemleri

Geçen hafta sonu eşim ve çocuğumla kamp yapmaya gittik Uludağ’ın eteklerinde. Ateşin başında otururken aklıma bir proje geldi, C# ile bir veritabanı bağlantısı kuracaktım ama telefonumdan hızlıca Dapper’ı denedim. Bağlantı stringini yanlış yazmışım herhalde, hata verdi sürekli, sinir oldum tabii. Neyse efendim, kampı bırakmadım ama eve dönünce düzelttim o hatayı, win oldu sonuçta 🙂

Evet, böyle küçük hatalar insanı motive ediyor bazen. Şimdi asıl konuya gelelim, C# geliştirirken veritabanı işleri kaçınılmaz. Ben özellikle REST API’ler için .NET kullanıyorum ve Dapper’ı seviyorum, çünkü Entity Framework’e göre daha hafif. MySQL ile entegre etmek de pratik, özellikle PostgreSQL’e alternatif arıyorsan. Bu yazıda kendi deneyimlerimden yola çıkarak anlatacağım, adım adım değil ama pratik ipuçları vereyim.

MySQL’i neden tercih edeyim ki diye sorarsın belki. Aslında açık kaynak, ücretsiz ve performanslı, büyük projelerde bile idare eder. Ben Bursa’da çalışırken bir projede MySQL kullandım, veri hacmi büyüdükçe sorun çıkmadı. Dapper ise micro-ORM, SQL yazmana izin veriyor ama mapping’i otomatik yapıyor. Neticede kodun daha temiz oluyor, fazla abstraction yok.

Dapper’ı Kurmak ve Bağlantı Ayarları

Öncelikle NuGet’ten Dapper’ı ekliyorsun projene. .NET Core için console app aç, sonra Package Manager Console’da Install-Package Dapper yaz. MySQL connector da lazım, MySqlConnector paketini yükle. Bağlantı stringini appsettings.json’a koy, şöyle bir şey: “Server=localhost;Database=TestDB;Uid=root;Pwd=pass;”. Benim deneyimime göre localhost’ta test ederken sorun çıkmıyor ama production’da SSL eklemeyi unutma.

Bağlantıyı açmak basit, IDbConnection interface’ini kullanıyorsun. Mesela using (var connection = new MySqlConnection(connectionString)) { } bloğu içinde query’lerini çalıştır. Evet gayet güzel çalışıyor derken, bir keresinde connection’ı kapatmayı unutmuşum, memory leak olmuş, debug ettim saatlerce. Neyse, using statement ile otomatik dispose oluyor, rahat ol.

Bu arada aklıma geldi, geçen ay bir elektronik devre tasarımı yaparken benzer bir hata yaşadım, bağlantı kopuyordu sürekli. Sanırım kablo hatasıydı, ama kodlamada da aynı mantık geçerli, bağlantıyı sağlam tut.

Basit CRUD Örnekleri

Şimdi veri ekleme işlemine bakalım. Bir User tablosu varsayalım, id, name, email sütunları olsun. Insert için connection.Execute(“INSERT INTO Users (Name, Email) VALUES (@Name, @Email)”, new { Name = “Ali”, Email = “ali@example.com” }); Bu kadar. Dapper parametreleri otomatik bind ediyor, SQL injection’a karşı güvenli. Ben bir API’de bunu kullandım, 1000 kayıt ekledim saniyede, performans süper.

Okuma için Query metodu var. var users = connection.Query(“SELECT * FROM Users WHERE Name = @Name”, new { Name = “Ali” }).ToList(); Sonra foreach ile dolaşırsın. Aslında LINQ ile birleştirince daha güzel oluyor, ama Dapper raw SQL’i teşvik ediyor. Hatırlamıyorum tam ama bir projede join’li query yazdım, karmaşıklaştı biraz, o yüzden simple tutmak en iyisi.

Fakat update ve delete de benzer. connection.Execute(“UPDATE Users SET Email = @Email WHERE Id = @Id”, new { Id = 1, Email = “new@example.com” }); Delete için WHERE şartı koymazsan hepsini siler, dikkat et : ) Ben bir keresinde unuttum, test veritabanını temizledim, güldük geçtik.

Neyse efendim, pratik bir örnek vereyim. Diyelim ki bir REST API geliştiriyorsun, controller’da [HttpGet] metodu içinde Dapper kullanıyorsun. Önce dependency injection ile connection’ı inject et, IServiceCollection’a AddScoped ekle. Sonra metodunda query çalıştır. Bu şekilde dependency’leri yönetmek kolaylaşıyor.

Bu arada, MySQL’in avantajı community desteği bol, forumlarda her sorun çözülüyor. MySQL docs sitesinde temel bağlantı ayarları var, oraya bakabilirsin. Gerçi ben genelde Stack Overflow’a soruyorum, hızlı cevap geliyor.

Soru sorayım mı, sen MySQL mi yoksa PostgreSQL mi kullanıyorsun? Bana göre ikisi de iyi ama MySQL daha hafif projelerde ideal. Sanırım büyük verilerde PostgreSQL öne çıkıyor, galiba öyleydi.

Gelişmiş Kullanımlar ve İpuçları

Şimdi stored procedure’lere değineyim. Dapper onlarla da uyumlu, connection.Query(“CALL GetUsersByAge(@Age)”, new { Age = 30 }); diye çağırıyorsun. Ben bir projede bunu kullandım, veritabanı tarafında logic’i tutmak için. Avantajı, kod temiz kalıyor, dezavantajı debugging zor. Neticede, simple query’ler için raw SQL yeterli oluyor.

Async versiyonunu unutma, özellikle API’lerde. connection.QueryAsync ile await ekle. Performansı artırıyor, thread block etmiyor. Benim bir REST API’mde sync kullandım başta, yavaşladı site, async’e geçince düzeldi. Bu arada Bursa trafiğinde kodlama yaparken async düşünmek lazım, her şey paralel gidiyor : )

Mapping için custom type handler yazabilirsin, mesela DateTime için. Ama genelde default yeterli. Bir keresinde enum mapping’te takıldım, Dapper otomatik yapmıyor, manuel handler ekledim. Detaylarını bilmiyorum ama Google’da ‘dapper enum mapping mysql’ ara, örnekler çıkar.

Gerçi bazen Dapper yerine ADO.NET’e dönüyorum, daha kontrolcü. Fakat Dapper’ın hızı cezbedici, özellikle milyonlarca satırda. Sanırım bir benchmark’ta EF’den 3 kat hızlıydı, tam hatırlamıyorum ama öyle bir şeydi.

Bu arada, elektronik devrelerle uğraşırken benzer veri akışı yaşıyorum, sensör verilerini MySQL’e yazıyorum C# ile. Gömülü sistemlerde Dapper pratik, lightweight olduğu için. Neyse, konudan sapmayayım.

Potansiyel sorunlara değineyim. Connection pooling’i etkinleştir, MySQL connector’da default açık ama poolingSize ayarla. Ben 100’e koydum bir projede, concurrent request’lerde sorun çıkmadı. Başka bir sorun charset, UTF8 kullan, Türkçe karakterler için.

İşte bir kod örneği vereyim insert için.

using Dapper;
using MySqlConnector;

public void AddUser(string name, string email)
{
    using var conn = new MySqlConnection(_connectionString);
    conn.Execute("INSERT INTO Users (Name, Email) VALUES (@Name, @Email)", new { Name = name, Email = email });
}

Bu kodu controller’a koy, çalışır. Açıklama olarak, parametreler anonymous object ile geçiliyor, güvenli. Alternatif olarak stored proc çağırabilirsin, ama bu simple yeterli.

Fakat transaction’lar da önemli, birden fazla işlemde. connection.UseTransaction(transaction); ile sar. Ben bir API’de iki tabloyu güncellerken kullandım, rollback için hayat kurtardı hatada.

Sonuç olarak, C# ile MySQL ve Dapper kombinasyonu benim favorim, hızlı ve esnek. Eğer yeni başlıyorsan, küçük bir proje yap, alışacaksın. Bir sitede görmüştüm detaylı tutorial, link bulamadım ama Google’da ‘csharp dapper mysql tutorial’ yaz, bol kaynak çıkar. Sen de dene, deneyim paylaş, ne güzel olur değil mi?

Açıkçası ben memnunum bu setup’tan, özellikle Vue.js frontend ile entegre ederken REST API’ler sorunsuz. Neyse efendim, bir dahaki yazıda belki jQuery ile veri çekmeyi anlatırım. Hoşça kalın.