• Foruma hoş geldin 👋 Ziyaretçi

    Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

C# Repository Design Pattern'i ADO.NET'e uygulama Hk.

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Aktiflik
Çevrimdışı
Katılım
10 Mar 2021
Mesajlar
882
Çözümler
116
Aldığı beğeni
1,002
Excel V
Office 2021 TR
Konuyu Başlatan
Arkadaşlar merhaba.
EntityFramework, EntityFrameworkCore gibi ORM yapılanmalarında sıkça kullanılan yöntem olan Repository Design Pattern'in ADO.NET (System.Data.OleDb ve System.Data.SqlClient) yöntemi ile yapıldığına dair herhangi bir eğitim videosuna rastlamadım. Ve ayrıca kod paylaşan sitelerde de görmedim. Böyle bir şey yapılabilir mi düşüncesine girdim ve elimden geldiğince bir şeyler yapmaya çalıştım. Umarım işine yarayan birileri çıkar.

Bu düşüncemin oluşmasını sağlayan youtube kanallarına da ayrıca teşekkür etmek isterim. Onların EntityFramework ve EntityFrameworkCore eğitim serileri olmasaydı böyle bir şey başarmam mümkün değildi.
bkz: , ,

Öncelikle veritabanımızdaki her bir tablomuzu birebir temsil eden class'lar oluşturmamız gerekiyor. Bu her bir kaydın ekleme, güncelleme, silme gibi operasyonlarını tek bir yerden yönetmek için gerekli.

Öncelikle soyut bir sınıf oluşturuyoruz ve bütün tablolarımızda ortak olan alanlarımızı burada tanımlıyoruz.

Bu ortak alanlar ID, InsertedDate, UpdatedDate, DeletedDate, DataStatus gibi alanlar olabilir diyerek bu alanları ortak olarak tanımladım.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

ID, InsertedDate, UpdatedDate, DeletedDate gibi alanlar int, DateTime gibi temel veri tipleri iken DataStatus alanı ise DataStatusEnum olarak geçiyor. Bunu da kendimiz tanımlayabiliyoruz. Aşağıda DataStatusEnum kodlarını görebilirsiniz.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Bu iki temel kodla entity sınıfımızın alt yapısını oluşturmuş olduk.

Bu aşamada örnek bir entity tanımlayalım.

aşağıdaki kod örnek bir entity'miz oldu. Buradaki ":BaseEntity" soyut sınıfımızın özelliklerini Kisiler class'ımıza hiç yazmadan aktarmış olduk. Bu yöntemle bütün class'lara tek tek ID gibi alanları yazmaktan kurtuluyoruz.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Entity sınıfımızı da tanımladıktan sonra bu aşamada Repository'mizin içinde bulunması gereken metodları içinde barındıracak olan interface'imizi tanımlayacağız.

Bu interface repository kodlarımızın içinde neler olacağını bize gösteriyor. Bu repository içinde <T> kısımları tablolarımızı temsil ediyor.
satırlardaki sol tarafta bulunan bool, void, List<T>, T gibi ibareler bize metodun nasıl davranacağını, ve geriye ne döndüreceğini tanımlıyor.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Artık repository kodlarımızı yazmaya başlayabiliriz.
Repository kodlarımızı interface'den implemente ettikten sonra interface'de bulunan geri dönüş değerlerini kodlamaya başlayabiliriz.

Burada dikkat etmemiz gereken Repository sınıfından türeteceğimiz veri erişim sınıflarında sadece operasyonları göstermek istiyoruz. Repository sınıfında ihtiyacımız olan yardımcı metodları dışarıdan erişime kapalı tutmak istiyoruz. Bu aşamada önümüze iki seçenek çıkıyor, ya repository sınıfımızın içinde private olarak tanımlayacağız. Ya da başka bir abstract sınıfta tanımlayıp daha sonrasında repository sınıfımızda inherit edeceğiz.

Öncelikle repository sınıfımızda ihtiyaç duyacağımız yardımcı metodları tanımlayacağımız sınıfın kodlarını verelim.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

bu kodlar bize repository sınıfında destek olacak.

şimdi gelelim repository kodlarımıza. Aşağıdaki kodlar bütün sınıflar için Add, Update, Delete gibi operasyonları gerçekleştirebileceğimiz kodlar.
Dikkat ederseniz hala yukarıdaki <T> gibi <TEntity> ile generic olarak çalışıyoruz. Yani hangi tip için çalışacağımızı hala bilmiyoruz.
Daha sonra her bir entity için açılacak data access sınıflarda bu TEntity'nin yerini veritabanındaki tablolarımızı temsil eden tablolar alacak.

Dikkat ederseniz bazı kodların için doldurulmamış ve throw new NotImplementedException(); satırı ile hata göndermesi için kodlanmış gibi görünüyor.
Bu paylaştığım kodlar halen tamamlanmamış üzerinde çalışmaya devam ettiğim kodlar olduğu için bu alanlar da tamamlandıkça buraya eklenecek.
İşin zor kısmını atlattığım için geri kalan kısımları kolay olarak gördüğümden bunları kısa sürede tamamlayabileceğimi umut ediyorum.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

veritabanına sorgular gönderebileceğimiz bütün sınıfları oluşturduktan sonra elimizdeki Kisiler sınıfı için veriye erişim için sınıfımızı açabiliriz.
Aşağıdaki kod ile artık Kisiler sınıfımız için bütün insert, update, delete gibi metodlarımızın tamamını yazmış olduk.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

bir başka sınıf için tekrar tekrar aynı kodları yazmak yerine yine aynı yöntemle bütün operasyonları ekleyebileceğiz.
Diyelim ki Urunler diye bir tablo daha ekledik. Bu sınıf için yukarıdaki gibi UrunlerDAL classı tanımlayarak bütün operasyonları eklemiş olacağız.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

yukarıdaki kodda da görüldüğü gibi yeni eklediğimiz tabloya insert update delete gibi metodları eklemek için sadece UrunlerDAL class'ı tanımlamamız yetiyor.
 
Son düzenleme:
Bu kodları şuan üzerinde çalıştığım bir projede uyguladım ve son derece sağlıklı bir şekilde çalışıyor.

Ayrıca bu kodları nereye yazacağız? Nasıl kullanacağız? Nasıl çalışmasını sağlayacağız? gibi soruları olanlar için ayrıca çalışan örnek bir proje hazırlayıp burada paylaşacağım. Şimdilik buna vaktim olmadığından ekleyemedim.

Projenin eksik tarafları malaesef çok bunlar aşağıda listelediğim gibi;
1. DTO dediğimiz (Data Transfer Object) nesneleri şimdilik desteklemiyor.
2. JOIN lerle oluşturulan select sorgularını desteklemiyor.
3. Aggregate Fonksiyonların kullanıldığı select sorgularını desteklemiyor.

bunlar projenin çok büyük eksikleri. Hangilerini çözebilirim emin değilim. Fakat bu eksikler arasından DTO'ları çözebileceğim konusunda ümitliyim. Diğerlerini nasıl çözebileceğim hakkında en ufak bir fikrim yok.

En azından her bir tablo için ayrı ayrı Ekle, Sil, Güncelle gibi metodları her defasında tek tek yazmaya uğraşmaktan kurtulmuş oluyoruz.
 
Adsız.jpg

proje eklemek için vaktim yok ama nasıl kullanılacağı ile ilgili resim ekliyorum. Örneği açıklayayım.
Operasyonlarını kullanacağımız Cariler adlı sınıfın DAL katmanını new'liyoruz veritabanı yolunu göstererek.
Cariler cari = dal.GetByID(3); satırı ile 3 ID numaralı cariyi seçiyoruz ve cariye ait bilgileri cari olarak tanımladığımız değişkenin içine alıyoruz.

Bu değişkende gerekli değişiklikleri yaptıktan sonra dal.Update(cari) metodunu kullanarak yapmış olduğumuz değişiklikleri veritabanına göndermiş oluyoruz.

Windows Forms kısmında ya da hangisini kullanıyorsanız diğer Frontend katmanlarında bu kadar temiz kod yazmamızı da sağlıyor.
 
Geri
Üst