Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Entity Framework – Code First Migrations İşlemleri

Merhaba,

Her projede olduğu gibi Code First yaklaşımıyla inşa ettiğimiz projemizde de güncellenmesi gerekecek noktalar kaçınılmaz olacaktır. Gerek kodlarda, gerekse de programın akışını sağlayan algoritmada düzenlenme olacaksa da bu yazımızı asıl ilgilendiren veritabanının güncellenmesi gereken durumlardır. Biliyoruz ki, Code First deseni uygulanan bir projede veritabanına direkt olarak müdahale etmek oldukça sakıncalıdır. Haliyle yapacağımız ekleme, çıkarma veyahut güncelleme durumlarını tabloları temsil eden classlar üzerinde gerçekleştirmeli ve Generate etmeliyiz.

Tabi şuana kadar yaptığımız tüm işlemleri SQL Server’dan fiziksel veritabanını silip, yeniden yükleyerek gözlemlemiş bulunmaktayız. İşte, Migration yapıları sayesinde yaptığımız yenilikleri Visual Studio üzerinden hızlıca fiziksel veritabanına yansıtabileceğiz. Anlayacağınız, kod kısmında yaptığımız değişiklikleri veritabanına yansıtmaya Migration demekteyiz.

Migrations yapısını kullanabilmek için bize “Package Manager Console” penceresi gerekmektedir. Eğer ilgili pencere sizde açık değilse “Tools” -> “NuGet Package Manager” -> “Package Manager Console” kombinasyonunu takip ederek açabilirsiniz.

Entity Framework - Code First Migrations İşlemleri

Entity Framework – Code First Migrations İşlemleri

Migrations yapısını aktifleştirmek için “Package Manager Console” üzerinden “enable-migrations” komutunu kullanmalıyız.
Şimdi üzerinde çalıştığımız bir projede Migrations yapısını aktifleştirelim.

Entity Framework - Code First Migrations İşlemleri

Entity Framework – Code First Migrations İşlemleri

Bu işlemi yaptıktan sonra projemizde aşağıdaki gibi “Migrations” isimli bir klasör oluşmaktadır.

Entity Framework - Code First Migrations İşlemleri

Entity Framework – Code First Migrations İşlemleri

İlgili klasör içerisinde Migrations ayarlarını gerçekleştireceğimiz “Configuration.cs” isimli dosyamız mevcuttur. Dosyamıza şöyle bir göz atarsak eğer;

namespace EF.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<EF.Model.Context.OkulDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(EF.Model.Context.OkulDBContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
}

“Configuration.cs” sınıfını şöyle bir incelersek eğer “DbMigrationsConfiguration” sınıfından kalıtım alarak Context sınıfımıza işaretlenmiştir. Bunun yanında constructurında “AutomaticMigrationsEnabled” özelliğine “false” değeri atanmıştır. Bu(AutomaticMigrationsEnabled) özelliği sayesinde otomatik olarak veritabanını güncelletebiliyoruz. Haliyle “false” değerde olunca bu özellik kapalı olmaktadır. O yüzden “true” değerini set ediyoruz.

    internal sealed class Configuration : DbMigrationsConfiguration<EF.Model.Context.OkulDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }
.
.
.
    }

Bu işlemlerden sonra gelin veritabanını güncelleyelim.

Entity Framework - Code First Migrations İşlemleri Entity Framework - Code First Migrations İşlemleri
Güncellemeden önce Güncellerken(update-database) Güncellemeden sonra

Gördüğünüz gibi veritabanı “update-database” komutu sayesinde anında güncelleyebildik. Tabi ilk güncelleştirmede veritabanıda yoksa oluşturulmaktadır.

Yeni tablo eklediğinizde ya da var olan bir tabloya ekleme, çıkarma veyahut güncelleme yaptığınızda “update-database” komutunu çalıştırmanız yeterlidir.

AutomaticMigrationDataLossAllowed Özelliği

“AutomaticMigrationDataLossAllowed” özelliğinden bahsetmezsek olmaz. Yapacağınız tablo güncelleme durumlarında, tablonun dolu olma olasılığında varsayılan olarak veriler güvence altına alınmaktadır. Bizde bu(AutomaticMigrationDataLossAllowed) özellik sayesinde bu durumu aşabilmekte ve verilerin güvenirliğini göz ardı edebilmekteyiz. Doğal olarak ilgili özellik “false” default değerine sahiptir. Biz constructurda ilgili özelliği çağırarak “true” değerini set edebiliriz.

    internal sealed class Configuration : DbMigrationsConfiguration<EF.Model.Context.OkulDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }
.
.
.   }

Migrasyon Ekleme

Model değişiklikleri için migrasyon eklemek için “Add-Migration” komutunu kullanarak “Add-Migration [Migrasyon Adi]” prototipini uygulayabilirsiniz.

Entity Framework - Code First Migrations İşlemleri

Entity Framework – Code First Migrations İşlemleri

Entity Framework - Code First Migrations İşlemleri

Gördüğünüz gibi migrasyonuda bu şekilde eklemekteyiz.

Bir yazımızın daha sonuna gelmiş bulunmaktayız.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…

Bunlar da hoşunuza gidebilir...

49 Cevaplar

  1. ahmet dedi ki:

    Merhaba bir problemim var mesela içinde veri olan modeldeki bir kolon adını güncellediğimde kolondaki veriler siliniyor bunun çözümü varmıdır.

    • Gençay dedi ki:

      Merhaba,

      Konuyla alakalı bir bilgim olursa size haber vereceğim. Eğer çözüm bulursanız lütfen bildiriniz.

    • Bora dedi ki:

      Verilerine zarar gelmeden kolon ismi değiştirmek istiyorsan Modelin içindeki değiştirmek istediğin sütuna bu şekilde yazarak [Column(“YeniAdAlanı”)] public string Ad { get; set; } yeni kolon ismi belirtmiş olursun sonra nuget packet manager consoldan Update-Database yazarak değiştini görebilirsin

  2. OĞUZHAN SARI dedi ki:

    Merhaba,
    Ben daha bu code first entitiy olayına ilk defa giriyorum.
    Bu yazı ve başka yerdeki bir yazı ve de youtube da bir kaç video (yabancı) izleyerek yapı oluşturdum.

    Şimdi aşağıdaki şekilde Products tablosu oluşturdum. İlk update-database işleminde.

    public DbSet Products { get; set; }

    Bunun class ıda şöyle

    namespace BiEntities.Models
    {
    public class Product
    {
    public int ID { get; set; }
    public decimal Price { get; set; } = 0;
    public virtual List Contents { get; set; } = new List();
    }
    }

    vede Contents class ı

    namespace BiEntities.Models
    {
    public class ProductContent
    {
    public int ID { get; set; }
    public string Name { get; set; }
    public string Detail { get; set; }
    public string Keywords { get; set; }
    public string SiteTitle { get; set; }
    public string Description { get; set; }
    }
    }

    Şimdi hiç bir sorun yok tablolar başarıyla eklendi.

    Benim sorum şu;
    Bir sütun ekledim,
    Bir sütun çıkardım,
    Bir tablo ekledim,
    Bir tablo çıkardım

    gibi olayları nasıl gerçekleştiriyoruz.

  3. serkan mendi dedi ki:

    Selamlar,
    Diyelim ki bir projem var, aynı projeyi aynı anda 10 farklı firma kullanıyor.Proje Winform olduğu için Her birinin Sql serverı ve Dbsi ayrı.Ve neredeyse hergün bir kolon yada tablo ekleniyor.Size bu işlemleri Veri kaybetmeden nasıl yapabilirim sizce..
    Bunun bir yolu varmı?

    • serkan mendi dedi ki:

      Demek istediğim her bir firmanın dbsini elimdeki Exe ile uyumlu hala getirebilmek için veri kaybetmeden nasıl güncellerim

  4. CSharper dedi ki:

    Tablo isimlerindeki S-ES takilarindan kurtulmak icin tablo isminin basina TableAttribute kullanabilirsin. Örnek [Table(“Company”)] seklinde. Yada Configuration sinifinda OnModelCreating metodunu override ederek içerisine Context.Conventions.Remove(); komutunu yazabilirsin.

  5. Ali Haydar dedi ki:

    Merhaba,

    classda yaptığımız değişikliği database uygulamak için add-migration ve update-database yapıyoruz kodda çalıştığı için problem yok yaptığım değişikler database uygulanıyor.

    fakat exeyi başka bi pcde çalıştırmak istediğimde o pcde ki database güncelleme yapmıyor hata veriyor. bu sorunu aşmanın yolu nasıl oluyor.

    • Gençay dedi ki:

      Merhaba,

      İlgili database’in o başka pc(ler)de de bulunması gerekmekte ve ayriyetten her bir pcnin server provider adresi o pcye özel olarak değiştiği göz önüne alınarak ilgili programın server bilgileri o pcye özel gerektiği gibi güncellenmelidir.

    • çağlar dedi ki:

      Mesela database yolunu bir text dosyasında tutup oradan okuyabilirsin. Bu şekilde istediğin pc den istediğin özellikleri değiştirebilirsin.

  6. BEDRETTİN dedi ki:

    Merhaba codefirst ile tüm tabloları kod kısmında oluşturdum. Ama mesela dışardan iller tablosu gibi hazır tabloları direk veritabanı kısmından nasıl ekleyebilirim umarım anlatabilmişimdir .

    • Gençay dedi ki:

      Merhaba,

      Harici veritabanlarını yahut tabloları Code First yöntemiyle uygulamaya dahil etmeniz neredeyse mümkün değil. İlgili tablolar baştan Code First ile modellenmeli ve migrate edilmelidir.

      • BEDRETTİN dedi ki:

        İl il.e ülke gibi DDOWNLİST de kullanacağım tabloları codefirst ile nasıl projeme ekleyebilirim. Onları da her proje başlangıcında modeller den mi oluşturulup doldurulmalı.

      • BEDRETTİN dedi ki:

        Peki il, ilçe, ülke gibi dropdownlist lere çekeceğim tabloları nasıl oluşturmam gerekiyor. Her proje başlangıcında model den mi oluşturulması gerekiyor.

  7. MithGokturk dedi ki:

    Merhaba Codefirst üzerinden update database işlemini yaptığım zaman projemde bir hata veriyor. Bu sorunu nasıl çözebilriim.

    Aldığım hata;

    The type initializer for ‘System.Data.Entity.Migrations.DbMigrationsConfiguration`1’ threw an exception

    .

  8. Gülis dedi ki:

    Merhaba hocam,
    Bütün aşamaları yapmama ragmen sql tarafında database’im oluşmadı neden olabilir acaba?

  9. Oğuz dedi ki:

    Merhabalar.

    Bir bilgisayar ve o bilgisayarda kurulu olan mssql serverda uygulamayı sorunsuz çalıştırıyorum. Başka bir bilgisayarda aynı uygulama üzerinde çalışmak istediğimde neler yapmam gerekiyor acaba ?

    – connection string’i düzenleyeceğim,
    -migrations klasörünü sileceğim,

    başka neler yapmam gerekiyor. Çünkü denediğimde hata almaktayım.

    Saygılarımla.

    • Oğuz dedi ki:

      Bunu code first yaklaşımı ile yaptığımı eklemeyi unutmuşum.

    • Gençay dedi ki:

      Merhaba,

      Migrationları silmenize gerek yoktur. Sadece connection string’i ilgili bilgisayarın sunucusuna göre düzenleyiniz ve tekrar migrate(update) ediniz.
      Kolay gelsin.

  10. murat sağlam dedi ki:

    hocam selamlar update-database sırasında hata almaktayım bir türlü database oluşturamadım

    PM> enable-migrations ———–(migrations klasörü ve configuration.cs oluştu)
    Checking if the context targets an existing database…
    Code First Migrations enabled for project sitem.
    PM> update-database
    Specify the ‘-Verbose’ flag to view the SQL statements being applied to the target database.
    No pending explicit migrations.
    Applying automatic migration: 202004151240476_AutomaticMigration.
    Running Seed method.
    PM>
    update dediğim de bu yanıtı alıyorum yardımcı olabilir misiniz 🙂

  11. gökhan dedi ki:

    Selamlar,

    Uygulamayı kuracağımız bazı yerlerde ssms olmadığı ve internete kapalı olduğu için bu işlemi web arayüzü üzerinden yapmak istiyorum. update-database komutunu bir controller aracılığı ile nasıl tetikleyebilirim? Yapmak istediğim aslında internette yer alan hazır cms’lerin installation alanı gibi bir arayüz hazırlamak. Bu konuda bir fikir verebilir misiniz?

  12. Samet Can Karataş dedi ki:

    Hocam Merhaba,
    Bir projede her kayıt olan kullanıcı için bir şema oluşturmaya çalışıyorum. Bunu otomatik bir şekilde kod üzerinde yapabilmek için verebileceğiniz bir örnek veya gösterebileceğiniz bir yol var mı?
    Teşekkürler

    • Gençay dedi ki:

      Merhaba,

      Sanırım Code First ile bir User modeli oluşturmak istiyorsunuz. Peki bu makale ihtiyacınız için yeterli olmadı mı?

      • Samet Can Karataş dedi ki:

        Örnek vererek anlatayım hocam,
        Veritabanımda kullanıcılar ve ürünler adında iki tablom var. Kullanıcı kayıt olduğunda kullanıcı tablosuna eklememi yapıcam ve bu kullanıcı için yeni bir şema oluşturarak buraya public şemamda bulunan ürünler tablosunun bir kopyasını oluşturmak istiyorum. Bu sayede her kullanıcıya özel bir şema ve ürünler tablosu oluşturmayı hedefliyorum.

        • Gençay dedi ki:

          Tekrar merhaba,

          Şema’dan kastınız nedir? Fiziksel model olan class mı? Tam anlayamadım! Biraz daha açar mısınız?

          • Samet Can Karataş dedi ki:

            Bir kullanıcı sisteme kayıt olduğunda kullanıcılar tablosuna kullanıcı eklendiğinde bu kullanıcının adıyla bir veritabanı şeması oluşturmak istiyorum. Bu şemaya ürünler tablosunu oluşturmak istiyorum.
            her üye için bir şema şema içerisinde ürünler tablosu yani. Aşağıdaki resimlerde durumu anlatmaya çalıştım


          • Gençay dedi ki:

            Bu hangi veritabanı?

          • Samet Can Karataş dedi ki:

            postgresql hocam, pgadmin arayüzü. Bahsettiğim işlemi query ile yaptım oldu bu arada ben bunu query kullanmadan yapmak istiyordum.

            var sql = string.Format(“CREATE SCHEMA {0} CREATE TABLE Products(title text, release date, awards text[]) CREATE VIEW winners AS SELECT title, release FROM Products WHERE awards IS NOT NULL; “, entity.CompanyName);
            context.Database.ExecuteSqlCommand(sql);

  13. Mehmet dedi ki:

    Migration özelliğinin update database komutunun runtime’da çalıştırabilir miyiz? Müşteri bilgisayarında versiyon geçişlerini harici olarak değil de migration motoruna adapte edebilir miyiz. Burada Migration bilgisinin program klasörüne export edilmişliği gibi bir şey gerekiyor gibi.

  14. C dedi ki:

    Hocam selamlar,
    ‘FK_Blogs_CategorySubheadings_CategorySubheadingId’ is not a constraint.
    Could not drop constraint. See previous errors.
    Bu hatayı alıyorum çok uğraştım yapamadım yardım eder misiniz. Code firste pek hakim değilim kurcaladım verileri bağlantıları vs. o yüzden aldım sanırım bu hatayı. ManyTo-Many olayını falan yapmam gerekiyormuş sanırım ama yapamadım anlamıyorum. Porjem bayağı ileriledi burada takıldım .

  15. songül dedi ki:

    Merhaba update-database yaptığım zaman database sql aktardığını belirtiyor. Hata vermiyor ama database kurulmuyor bu konu ile hiç karılaştınız mı?

  16. Yusuf dedi ki:

    update-database dedikten sonra böyle bir hata alıyorum. Yardım edebilir misiniz?
    specify the ‘-verbose’ flag to view the sql statements being applied to the target database.

  17. Bahri Can Öz dedi ki:

    enable-migrations yaptıktan sonra bu hatayı verdi çözümü nedir arkadaşlar
    The ADO.NET provider with invariant name ‘System.Data.SqlClient;’ is either not registered in the machine or application config file, or could not be loaded. See the inner exception for details.

  18. Mehmet Solak dedi ki:

    Merhaba @Bahri Can Öz

    App.config dosyasında connectionsitrin tagında providerName=”System.Data.SqlClient” eklemelisin..

    örnek connection string tagı

  1. 09 Ekim 2021

    […] Yukarıdaki tablolar için Migration işlemi uygulamayı konu dışı olduğu için burada göstermeyeceğim. Bu konuda bu linkten faydalanabilirsiniz. […]

Gençay için bir yanıt yazın Yanıtı iptal et

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir