Erdinç Yaşan

C# EFCORE DESIGNTIME

Bazı sebeplerden ötürü DbContext nesneninizi Webapi içerisinde değil de bir classlibrary projesi içerisinde tutmak isteyebilirsiniz, eğer böyle bir projeniz var ise Migration alma ve Veri tabanı güncelleme işlemlerinde DesignTimeDbContext ile ilgili bir hata alırsınız.

Şimdi bu projenin bir örneğini yapmak için öncelikle promizi oluşturalım aşağıdaki kodları sırayla çalıştıralım.

Kodları sırayla çalıştırdığınızda bir adet klasör klasör altında 3 adet proje (2si classlibrary ve 1i webapi) oluşturulacak sonrasında ise referans olarak ekleme işlemleri mevcut

Domain projesine herhangi bir referans eklemiyoruz Infrastructure projesine Domain projesini referans olarak ekliyoruz sonrasında ise MyApi projesine de Infrastructure projesini referans olarak ekliyoruz. Sıra geldi veri tabanı ve tablomuza karşılık gelecek olan classlar’ı oluşturmaya.

Domain altında bir adet Catalog adlı klasör oluşturdum ve bu klasör altında Blog adlı bir sınıf bu sınıf aşağıdaki şekildedir.

Şimdi de DbContext’imizi oluşturmamız gerekiyor.

Devam etmeden önce Microsoft.EntityFrameworkCore ve Microsoft.EntityFrameworkCore.Design ve SqlServer paketlerini Infrastructure projemize ekleyelim.

Aşağıdaki kodlar Infrastructure projesine gerekli paketleri kuracaktır.

Sonrasında Infrastructure projesi içerisinde Persistence adlı bir klasör oluşturdum ve bu klasörün altında AppDbContext adlı bir sınıf oluşturdum bu sınıf aşağıdaki şekildedir.

Burada DbSet property’sini eklemeyi unutmayın eğer eklemezseniz veri tabanında projeniz oluşmaz.

Şimdi gelelim veri tabanımızı kullanmaya bildiğiniz gibi veri tabanını WebApi içerisindeki servislerimize ekleyelim.

Şimdi veri tabanımızı servislerimize ekledik hadi gelelim ve migration almaya çalışalım.

Bu kodu çalıştırdıktan sonra ekrana hata almamız lazım yukarıda bahsettiğim hata aşağıdaki şekildedir

Unable to create an object of type ‘AppDbContext’. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

Burada Infrastructure projesi içerisindeki DbContext’imizi tasarım esnasında oluşturamadığından bahsediyor buradaki DbContext’i design esnasında yani projeyi çalıştırmadan oluşturabilmesi için bir adet işlem gerekli.

Persistence altında IDesignTimeDbContext interface’inden türetilmiş bir adet class oluşturuyorum benim oluşturduğum class aşağıdadır.

EFCore burada şunu demek istiyor IDesignTimeDbContextFactory interface’inden bir adet sınıf oluştur ve bu sınıftan bana AppDbContext dönsün.

Burada dikkat etmemiz gereken bir durum mevcut 1.si bizim DbContext sınıfımızı set etmemiz için ihtiyacımız olan şey nedir?

4.Satıra baktığınızda Constructor’ımızın DbContextOptions aldığını görebilirsiniz yani doğrudan geriye return new AppDbContext() diyemiyoruz. Bunun için DbcontextOptions’ını build etmemiz gerekiyor. Build etmek derken oluşturmamız ve new AppDbContext(options) şeklinde geçmemiz gerekiyor.

yukarıda sınıfın güncellenmiş satırlarını işaretledim bu satırlara dikkatli bir şekilde bakarsanız geriye bir AppDbContext sınıfını döndüğümü görmüşsünüzdür bu sınıfı kaydettikten sonra tekrar deneyelim ?

Vola! kodu çalıştırdıktan sonra eğer tüm adımları doğru bir şekilde takip ettiyseniz Infrastructure projesi altında Migrations klasörünün oluştuğunu göreceksiniz. Migration işlemini alabildik.Eğer sqlServer bağlantı metnini de verirseniz database update diyerek veri tabanını da oluşturabilirsiniz.

Sadece hata gidermek için gelenler buraya kadar okusa yeter, dahasını öğrenmek istiyorsanız buyrun devam edelim.

AppDbContextFactory classımıza dikakt ettiyseniz içerisinde string[] args parametrelerini alan bir fonksiyon mevcut, eğer bir üniversitede nesne tabalı programlamaya giriş dersi aldıysanız static void main(string[] args) ifadesi ile tanışıksınızdır, aslında buradaki string[] args ifadesi de aynı şeyi tetikliyor.

Şimdi biz migration eklerken konsolda neler dönüyor bir bakalım.

burada 1ve 2. satırlarda projeyi build aldığında görebilirsiniz eğer build işlemi başarılıysa devam ediyor.

3 ile işaretlediğim satırı lütfen es geçin benim yüklemiş olduğum dotnet ef tool’u 7.0.5 fakat proje içerisindeki eklemiş olduğumuz paket ef 7.0.13 bu uyarının sebebi bu bilseniz yeterli.

4 ile işaretlediğim alanda ise Done. ifadesini görmekteyiz yani işlem tamam. Peki ben bu AppDbContext sınıfındaki CreateDbContext(string[] args) ifadesi içerisinde Console.WriteLine() ile bir şey yazdırırsam ne olur? bakalım.

Yukarıda işaretlediğim satırda eklediğim işlemi görebilirsiniz.

Kırmızı ok ile işaretlediğim alanda bu çıktıyı görüyoruz. Buradan şunu söyleyebiliriz dotnet ef arka tarafta bir console uygulaması çalıştırıyor.

Peki string[] args ne ola ki?

Sınıfı aşağıdaki gibi güncelledim ve args içerisindeki arg’ları ekrana yazdırdım =)

Çalıştırdığım kod ve aldığım çıktı aşağıdaki gibidir.

Gördüğünüz gibi args değerli bomboş olduğu için sadece üstündeki ve altındaki ifadeleri yazdırdı. Peki nasıl args değerleri geçebilirim?

Eğer dotnet ef kodunu çalıştırırken işaretlediğim kutudaki gibi ifadesinden sonra bir metin veya metinler verirseniz bunlar projenize args olarak geçecektir.

Ve gördüğünüz gibi bu sefer mySqlServer şeklinde ekrana da yazdırdı.

Şimdi bunu niye anlattığıma gelecek olursak =)

Aşağıdaki gibi bir kullanım ile veri tabanınızın bağlantı dizesini parametre ile geçebileceğinizi göstermek istedim. Çoğu zaman bağlantı dizeleri appsettings.json altında tutulur fakat birden fazla kişi projeyi kullandığı zaman herkesin local environment’ındaki sql bağlantı dizesi farklı olabilir ; Örneğin ben Integrated Security=true kullanmıyorum bir başkası kullanabilir bunun için class’ımızı aşağıdaki gibi güncelleyebiliriz.

Artık bağlantı dizesi vermeden dotnet ef migrations add işlemi yapmaya çalıştığımızda şununla karşılaşacağız..

Ve tabiki de migration alma işlemimiz başarısız olacak.

doğru kullanım ise örnek için aşağıdaki gibi olabilir.

Burada Server ila başlayıp true ile biten ifadede kendi bağlantı metninizi verebilirsiniz ve veri tabanınızı güncelleyebilirsiniz.

Bu yazım da bu kadar olsun sağlıcakla kalın.

Exit mobile version