EntityFramework Core ile Execute Raw Sql lerin DTO model olarak sonuç dönmesi , Generic DbContext çözümü

Mucahid Uslu
3 min readDec 20, 2020

--

english version here..

Bildiğiniz üzere, entityframework core (core 3.1 ve .net 5 dahil), raw sql lerin execute edilmesinde bizi dönüş tipi olarak DbSet e zorluyor, bu yazımda DbSet oluşturmadan generic bir yapı kurarak kendi model sınıflarımız tipinde nasıl sonuç kümesi dönebiliriz bunu yazdığım bir mimari üzerinde anlatacağım.

Bu raw sql ler bir sorgu, bir function ya da stored prosedürün execute edilmesi olabilir, hatta stored procedure ün generic olarak execute edilmesi için de bir extension yazdım, yazımın devamında bulabilirsiniz.

Bunu yaparken, örneğimizde, -db first- entity sınıflarımızı scaffold komutuyla oluşturduğumuzu belirteyim, ancak ondan başka bir db context türeteceğiz ve yine ondan da generic bir db context türeteceğiz. Ve bunların hepsini veri erişim katmanına uygulayacağız, repository katmanını bunlarla muhatap etmeyeceğiz, çünkü repository bizim için sadece ve sadece business logic demek, orada DbSet vs. oluşturmak iyi bir tasarım asla olmaz.

Öncelikle dotnet ef core tools komutları ile ile veritabanımızdan entity setlerimizi oluşturduğumuzda öncelikle dbsets ve db contextimizi şu şekilde oluşturuyoruz,

Evet, gördüğünüz gibi, bu bizim domain dbcontext’imiz..

Şimdi, bundan bir tane db context türeteceğim, aslında doğrudan bir generic context türetebilirim, ancak yaparsam, başka bir makale konusu olan appsettings’deki bağlantı dizesiyle db bağlamı oluşturmak için onConfiguring yöntemini geçersiz kılamıyorum (* O yazıyı yazdıktan sonra buraya bir link koyacağım..)

Ve türetilmiş AppDbContext’imiz ,

Dilerseniz, generic tipler değil de, üst fotoğrafta göreceğiniz üzere, bu türetilmiş db context içerisinde kendi DbSet lerinizi oluşturup kullanabilirsiniz, ama bizim amacımız bu değil, daha genel , esnek ve iyi bir çözüm için, generic bir çözüm çalışıyoruz ve bu makaledeyiz,

Devam edelim konumuza o halde, şimdi, türetilmiş AppDbContext’imizden yine onu miras alarak generic bir dbcontext oluşturacağız,

Generic dbcontext’imizi yarattık ve onun için sadece bir tane generic tipte dbset, yani genel kullanım için dbset entity tanımladık, başka da tanımlamayacağız daha.

Şimdi bunu kullanma zamanı ,

FromRawSql yöntemini kullanarak bir sql yordamı çalıştıralım ve sonucu modele (DTO vb.) döndürelim.

# 1 Örneğin, generic db context kullanarak ürünleri alan ve bunları tProduct DTO sınıfında toplayan bir yöntemi kodlayalım;

public static List<tProduct> GetProducts(string pcode)

{

var result = new List<tProduct>();

using (var ctx = new GenericContext<tProduct>(_appDbContext.Database.GetConnectionString()))

{

result = ctx.Entities.FromSqlRaw<tProduct>(“select , exec etc… your query here “)

.Where(p => p.Code == pcode).ToList();

}

return result;

}

Ancak, stored procedure çalıştıran bir extension yazarsak bu daha da iyi bir çözüm olacaktır, iyi fikir , yola devam edelim ..

# 2 Örnek, base dbcontext üzerinde prosedürleri yürütmek için bir genişletme yöntemi yazalım,

Çok iyi görünüyor, şimdi bu extension için bir örnek yapalım, stored proc. execute edelim ve DTO nesnemize dönelim resultı,

Evet, Microsoft.EntityFrameworkCore’da base DbContext sınıfı için yazdığımız genişletme yöntemini uyguladık, böylece artık sonucu istenen dto nesnesine kolayca alabiliriz, burada dto modeli LoginResult’dur, bir varlık veya herhangi bir DbSet değildir.

İyi çalışmalar.

--

--

Mucahid Uslu
Mucahid Uslu

Written by Mucahid Uslu

Physics (Istanbul Technical University) , Software Engineer

No responses yet