5 min read

Database-first scaffolding: Veritabanından context ve model sınıfları oluşturma

Bu yazıda Entity Framework Core ve MySql veritabanı kullanılan bir projede hazır bir veritabanından yola çıkarak model ve context sınıflarını otomatik olarak oluşturduk. Ortaya çıkan sonuç projenin başlangıç aşamasında zaman kazandırıyor.
Database-first scaffolding: Veritabanından context ve model sınıfları oluşturma

Eğer elinizde halihazırda bir veritabanı bulunuyorsa, bunları temsil edecek model sınıflarını ve context sınıfını elle yazmanız gerekir. EF Core araçlarını kullanarak bunları scaffolding yöntemiyle otomatik olarak oluşturabilirsiniz.

Projenin tamamlanmış halini github'dan indirebilirsiniz.

gulangurman/dbfirst
Contribute to gulangurman/dbfirst development by creating an account on GitHub.

Kurulum

İlk olarak bir mvc projesi oluşturarak başlayalım.

dotnet new mvc -f netcoreapp3.1 -o dbfirst --no-https
cd dbfirst

Ardından EF Core 3.1 ve Mysql database provider paketlerini ekleyelim.

Provider olarak Pomelo'yu seçiyoruz; çünkü scaffolding konusunda Mysql.Data provider yetersiz kalıyor. Bunlara ek olarak Scaffolding yapabilmek için mutlaka Design paketini de yüklememiz gerekiyor.
PomeloFoundation/Pomelo.EntityFrameworkCore.MySql
Entity Framework Core provider for MySQL and MariaDB built on top of MySqlConnector - PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

Artık "dotnet run" komutuyla localhost:5000 adresinde mvc uygulamamız çalışacaktır.

dotnet add package Microsoft.EntityFrameworkCore --version 3.1.11
dotnet add package Microsoft.EntityFrameworkCore.Design --version 3.1.11
dotnet add package Pomelo.EntityFrameworkCore.MySql --version 3.2.4
dotnet run

Toparlamak gerekirse, proje tanımınız bu eklemelerden sonra şu şekilde olmalı:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.11" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.11">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.4" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.4" />
  </ItemGroup>

</Project>

Scaffold komutu ile veritabanı oluşturma

Bu yazıda daha önceki yazılarda gördüğümüz PeopleDB veritabanını altyapı olarak kullanacağız. DB-first yaklaşımı ile bu veritabanındaki tabloları temsil edecek olan model sınıflarının otomatik olarak oluşmasını sağlayacağız.

Öncelikle EF Core ile CLI yani komut satırından scaffolding yapmak için gereken komuta göz atalım:

dotnet ef dbcontext scaffold "connection-string" "provider-name" -o Models -f

Burada connection string alanına mysql bağlantı cümlesini yazacağız. Ayrıca -o flagi ile belirtilen modellerin konulacağı dizin adıdır. Burayı Models şeklinde standart bırakabilirsiniz. Şimdi kendi komutumuzu oluşturalım.

dotnet ef dbcontext scaffold "server=localhost;database=peopledb;user=peopledb_user;password=123456" Pomelo.EntityFrameworkCore.MySql -o Models -f

Siz de kendi bağlantı cümlenizi yerleştirerek herhangi bir veritabanını scaffold edebilirsiniz. Sonuç olarak model sınıfları ve context sınıfımız otomatik olarak oluşmuş olmalı.

Code-first ile Database-first scaffolding karşılaştırması

PeopleDB veritabanını daha önceden code-first yaklaşımla oluşturmuştuk. O zaman yazdığımız Order sınıfı ile scaffolding ile biraz önce oluşan Order sınıfını kaşılaştıralım. Burada hatasız olarak model sınıfının yeniden oluştuğunu görebiliyoruz.

Diğerlerine de göz atalım. Sol tarafta code-first projesindeki orijinal sınıfları, sağ tarafta da scaffolding ile oluşan sınıfları görüyoruz. Bütün modeller hatasız bir şekilde oluşturulmuş durumda.

Bir de context sınıfına bakalım. Soldaki code-first projesindeki orijinal context, sağdaki de scaffold ile yeni oluşturulan context. Bu da sorunsuz şekilde oluşturulmuş durumda.

Context sınıfında dikkat çeken bir nokta, Fluent API ile yapılan tanımlamaların son derece detaylı olması. Metinlerde kullanılacak karakter setine kadar ince detaylar mevcut.

DbContext'in dependency injection ile servislere eklenmesi

Bu noktada Startup içerisinde servislere context'imizi ekleyerek veritabanı işlemlerini tamamlayabiliriz.

public class Startup
{
    //...
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddDbContext<Models.peopledbContext>();
    }
    //...        
}

Dipnot: Pomelo kullanmasak olmaz mı?

Pomelo yerine Mysql.Data 8.0.20 provider da kullanabilirsiniz. Fakat bu durumda scaffolding yapılırken bazı hata veya uyarılarla karşılaşacağınız kesindir.

Örneğin Mysql.Data provider ile PeopleDB'yi scaffolding yaptığınızda datetime tipindeki alanların modele alınamadığını görürsünüz. Ayrıca controller ve view scaffold etmek konusunda da ben şahsen başarılı olamadım.

Bu problemi sadece Order ve context sınıflarına ikişer satır ekleyerek çözebiliriz. Fakat controller ve view scaffold edecekseniz başarısız olma ihtimaliniz çok yüksek.

public class Order
{
    //omitted...
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }        
}
modelBuilder.Entity<Order>(entity =>
{
    //omitted...
    entity.Property(e => e.DateCreated).HasColumnType("datetime");
    entity.Property(e => e.DateModified).HasColumnType("datetime");                
});

Son söz.

Bu yazıda Entity Framework Core ve MySql veritabanı kullanılan bir projede hazır bir veritabanından model ve context sınıflarını otomatik olarak oluşturduk. Ortaya çıkan sonuç bize projenin başlangıç aşamasında zaman kazandırıyor. Tekrar tekrar aynı şeyleri yazmak külfetinden bizi kurtarıyor.

MySql veritabanı tercih edenlerin Entity Framework kullanırken versiyon numaralarına mutlaka dikkat etmesi gerekiyor. Hatalarla uğraşmamak için kuracağınız nuget paketlerinin en yenisini değil, projenize uyumlu olacak versiyonunu seçmek konusunda dikkatli olmanızı öneririm.

Devam yazılarında yine MySql veritabanı kullanarak Entity Framework Core'un özelliklerini keşfetmeye devam edeceğiz. Bir sonraki yazıda görüşmek üzere, hoşçakalın.