MongoDbRepositoryExample · MongoDB ile Generic Repository Örneği

İfade ağacından filtre üreten; InsertOne, ReplaceOne ve DeleteMany davranışlarını generic repository altında toplayan MongoDB veri erişim çalışması.

Bir kişi kaydını soyadına göre bulmak, aynı soyadına sahip kişileri listelemek ve belirli bir koşula uyan belgeleri silmek benzer görünen ama sonuçları farklı işlemler. MongoDbRepositoryExample, bunları Ad ve Soyad alanlarından oluşan sade bir model üzerinden ele alıyor. Çözüm, .NET Core 3.1 hedefleyen bir konsol uygulaması ve onun kullandığı MongoRepository kütüphanesinden oluşuyor. Konsol örneği, MongoDB sürücüsünün çağrılarını doğrudan yapmak yerine model türünü ve arama koşulunu repository’ye veriyor.

Model türünden koleksiyon seçimine

MongoRepository<T> sınıfı, IRepository<T> sözleşmesini uygular ve belge türünü çağıranın belirlemesini sağlar. Oluşturucu, bağlantı adresini MONGO_URI, veritabanı adını ise MONGO_DATABASE ortam değişkeninden okur. Ardından IMongoCollection<T> referansını, türün adına göre alır. Dolayısıyla örnekte MongoRepository<Model> kullanıldığında hedef koleksiyonun adı Model olur. Bu tercih, aynı repository kodunu farklı belge sınıflarıyla kullanırken koleksiyon adını ayrıca geçme ihtiyacını ortadan kaldırır ve adlandırmayı doğrudan sınıf adına bağlar.

Uygulama, Program.cs içinde bir repository örneği ve bir kişi nesnesi oluşturur. Ekleme, sorgulama, güncelleme ve silme çağrıları yorum satırında gösterildiği için programı açmak bu işlemleri kendiliğinden yürütmez. Örneğin neyin çalıştığını incelemek için konsoldaki kullanım satırlarıyla kütüphanedeki yöntemleri birlikte okumak gerekir. Kütüphanenin veri işlemleri MongoDB C# sürücüsünün senkron metotlarını kullanır.

Aynı koşul, farklı sayıda belge

x => x.Soyad == "ExampleLastName" gibi bir ifade, Builders<T>.Filter.Where ile MongoDB filtresine dönüştürülür. Get, bu koşula uyan ilk belgeyi döndürür. GetAll metodunun koşul alan biçimi ise eşleşen belgeleri dolaşmaya açar. İki kişinin aynı soyadını taşıdığı bir koleksiyonda tek kayıt beklemek ile eşleşen kişilerin tamamını görmek arasındaki fark, çağrılan metotla belirlenir.

İki listeleme yolu da IQueryable<T> döndürür, ancak uygulamaları farklıdır. Parametresiz GetAll, koleksiyonun AsQueryable metodunu kullanır. Filtreli sürüm, koşulu Find çağrısına verir ve sonucu ToEnumerable().AsQueryable() ile sunar. Bu yüzden dönüş türünün aynı görünmesi, çağıranın daha sonra eklediği sorgu operatörlerinin iki yol üzerinden de aynı şekilde MongoDB’ye aktarılacağı anlamına gelmez.

Belgeyi değiştirmek ile eşleşmeleri silmek

Add, InsertOne ile tek belge ekler. Update, ReplaceOne çağırarak ilk eşleşen belgenin yerine verilen nesneyi yazar. Bu, örneğin yalnızca soyadı alanını hedefleyen bir alan güncellemesinden farklı bir işlemdir. Delete ise DeleteMany kullandığı için koşula uyan tüm belgeleri siler. Konsoldaki x => x.Ad == "ExampleName" örneği, aynı adı taşıyan birden çok belge olduğunda silmenin kapsamını görünür kılar. Repository ortak bir arayüz sunsa da her yöntemin bir belgeyi mi, tüm eşleşmeleri mi etkilediğini kullanılan sürücü çağrısı belirler.

Örneğin aynı soyadındaki kişilerden yalnızca birini değiştirmek istiyorsak filtreyi o kişiyi ayırt edecek şekilde kurmak gerekir. Örnek model ad ve soyadla sınırlı olduğu için, aynı adı ve soyadı taşıyan kayıtları bu iki alan üzerinden birbirinden ayırmak mümkün değildir.