Entity Framework - Hızlı Kılavuz

Entity Framework nedir?

Entity Framework, Microsoft'un .NET uygulamaları ve ilişkisel veritabanları arasındaki birincil etkileşim aracı olan 2008'de ilk kez piyasaya sürüldü. Entity Framework, yazılımınızdaki nesneler arasında ilişkisel bir veritabanının tabloları ve sütunlarıyla eşleştirmeyi basitleştiren bir araç türü olan bir Nesne İlişkisel Eşleştiricidir (ORM).

  • Entity Framework (EF), .NET Framework'ün bir parçası olan ADO.NET için açık kaynaklı bir ORM çerçevesidir.

  • Bir ORM, veritabanı bağlantıları oluşturmanın ve komutların çalıştırılmasının yanı sıra sorgu sonuçlarını alır ve bu sonuçları otomatik olarak uygulama nesneleriniz olarak gerçekleştirir.

  • Bir ORM ayrıca bu nesnelerdeki değişiklikleri takip etmeye yardımcı olur ve talimat verildiğinde, bu değişiklikleri sizin için veritabanına geri gönderir.

Neden Entity Framework?

Entity Framework bir ORM'dir ve ORM'ler, uygulamalarda kullanılan verileri kalıcı kılma görevini azaltarak geliştiricinin verimliliğini artırmayı amaçlamaktadır.

  • Entity Framework, veritabanındaki verileri okumak veya yazmak için gerekli veritabanı komutlarını oluşturabilir ve bunları sizin için çalıştırabilir.

  • Sorguluyorsanız, varlıklara LINQ kullanarak sorgularınızı etki alanı nesnelerinize göre ifade edebilirsiniz.

  • Entity Framework, veritabanındaki ilgili sorguyu yürütür ve ardından, uygulamanızda çalışmanız için sonuçları etki alanı nesnelerinizin örneklerinde somutlaştırır.

Piyasada NHibernate ve LLBLGen Pro gibi başka ORM'ler de vardır. Çoğu ORM tipik olarak etki alanı türlerini doğrudan veritabanı şemasına eşler.

Entity Framework daha ayrıntılı bir eşleme katmanına sahiptir, böylece örneğin tek varlığı birden çok veritabanı tablosuna veya hatta birden çok varlığı tek bir tabloya eşleyerek eşlemeleri özelleştirebilirsiniz.

  • Entity Framework, Microsoft'un yeni uygulamalar için önerilen veri erişim teknolojisidir.

  • ADO.NET doğrudan veri kümeleri ve veri tabloları teknolojisine başvuruyor gibi görünüyor.

  • Entity Framework, tüm ileriye dönük yatırımların yapıldığı yerdir, bu da birkaç yıldır böyle olmuştur.

  • Microsoft, tüm yeni geliştirmeler için ADO.NET üzerinden Entity Framework veya LINQ to SQL kullanmanızı önerir.

Kavramsal model

Veritabanı odaklı geliştirmeye alışkın olan geliştiriciler için Entity Framework'teki en büyük değişiklik, iş alanınıza odaklanmanıza izin vermesidir. Uygulamanızın, veritabanının yapabildikleriyle sınırlı kalmadan ne yapmasını istiyorsunuz?

  • Entity Framework ile odak noktası kavramsal bir model olarak adlandırılır. Bu, uygulamanızdaki nesnelerin bir modelidir, uygulama verilerinizi sürdürmek için kullandığınız veritabanının bir modeli değildir.

  • Kavramsal modeliniz veritabanı şemanızla aynı hizaya gelebilir veya oldukça farklı olabilir.

  • Kavramsal modelinizi tanımlamak için bir Görsel Tasarımcı kullanabilirsiniz, bu daha sonra uygulamanızda nihai olarak kullanacağınız sınıfları oluşturabilir.

  • Yalnızca sınıflarınızı tanımlayabilir ve Code First adlı Entity Framework özelliğini kullanabilirsiniz. Ve sonra Entity Framework kavramsal modeli kavrayacaktır.

Her iki durumda da Entity Framework, kavramsal modelinizden veritabanınıza nasıl geçeceğinizi belirler. Böylece kavramsal model nesnelerinize göre sorgulayabilir ve onlarla doğrudan çalışabilirsiniz.

Özellikleri

Entity Framework'ün temel özellikleri aşağıdadır. Bu liste, en dikkate değer özelliklere ve ayrıca Entity Framework hakkında sık sorulan sorulara göre oluşturulur.

  • Entity Framework bir Microsoft aracıdır.
  • Entity Framework, bir Açık Kaynak ürünü olarak geliştirilmektedir.
  • Entity Framework artık .NET yayın döngüsüne bağlı veya bağımlı değildir.
  • Geçerli Entity Framework sağlayıcısına sahip herhangi bir ilişkisel veritabanıyla çalışır.
  • LINQ'dan Varlıklara SQL komut üretimi.
  • Entity Framework, parametreleştirilmiş sorgular oluşturacaktır.
  • Bellek içi nesnelerdeki değişiklikleri izler.
  • Komut oluşturma, ekleme, güncelleme ve silme izni verir.
  • Görsel bir modelle veya kendi sınıflarınızla çalışır.
  • Entity Framework, Prosedür Desteği depolamıştır.

Entity Framework mimarisi, aşağıdan yukarıya, aşağıdakilerden oluşur:

Veri Sağlayıcılar

Bunlar, kavramsal şemaya göre programlama yaparken veritabanına bağlanmak için ADO.NET arabirimlerini soyutlayan kaynağa özgü sağlayıcılardır.

LINQ gibi yaygın SQL dillerini komut ağacı aracılığıyla yerel SQL ifadesine çevirir ve belirli DBMS sistemine karşı yürütür.

Varlık İstemcisi

Bu katman, varlık katmanını üst katmana maruz bırakır. Varlık istemcisi, geliştiricilere kavramsal şemayı temsil edecek sınıflar oluşturmaya gerek kalmadan varlık SQL sorgularını kullanarak satırlar ve sütunlar biçiminde varlıklara karşı çalışma yeteneği sağlar. Entity Client, temel işlevler olan varlık çerçeve katmanlarını gösterir. Bu katmanlara Varlık Veri Modeli adı verilir.

  • Storage Layer tüm veritabanı şemasını XML biçiminde içerir.

  • Entity Layer Bu aynı zamanda bir XML dosyası olan varlıkları ve ilişkileri tanımlar.

  • Mapping layer kavramsal katmanda tanımlanan varlıkları ve ilişkileri mantıksal katmanda tanımlanan gerçek ilişkiler ve tablolarla eşleyen bir XML dosyasıdır.

  • Metadata services Varlık İstemcisinde de temsil edilen, üst veride depolanan Varlık, Eşleme ve Depolama katmanlarına erişmek için merkezi API sağlar.

Nesne Hizmeti

Nesne Hizmetleri katmanı, uygulamalar ile veri kaynağı arasındaki etkileşim oturumunu temsil eden Nesne Bağlamıdır.

  • Nesne Bağlamının ana kullanımı, varlıkların örneklerini ekleme, silme gibi farklı işlemleri gerçekleştirmek ve değiştirilen durumu sorgular yardımıyla veritabanına geri kaydetmektir.

  • Varlıkların nesne örneklerine ilişkin veri sonucunu temsil eden Entity Framework ORM katmanıdır.

  • Bu hizmetler, geliştiricinin LINQ ve Entity SQL kullanarak sorgular yazarak birincil anahtar eşleme, değişiklik izleme vb.

Entity Framework 6'daki Yenilikler Neler?

Framework, modellemesinden çalışma zamanı davranışına kadar her şey üzerinde ayrıntılı kontrole sahip olmanızı sağlayan karmaşık bir API'ye sahiptir. Entity Framework 5'in bir kısmı .NET'in içinde yaşar. Ve başka bir parçası, NuGet kullanılarak dağıtılan ek bir derlemenin içinde yaşıyor.

  • Entity Framework'ün temel işlevi .NET Framework'te yerleşiktir.

  • Code First desteği, Entity Framework'ün bir görsel model yerine sınıfları kullanmasına ve EF ile etkileşim için daha hafif bir API'ye NuGet paketinde izin veren şey budur.

  • Çekirdek, sorgulama, değişiklik izleme ve sorgularınızdan SQL sorgularına ve nesnelere veri dönüşünden tüm dönüşümü sağlayan şeydir.

  • EF 5 NuGet paketini hem .NET 4 hem de .NET 4.5 ile kullanabilirsiniz.

  • Büyük bir kafa karışıklığı noktası - .NET 4.5, temel Entity Framework API'lerine numaralandırma ve uzamsal veriler için destek ekledi; bu, .NET 4 ile EF 5 kullanıyorsanız, bu yeni özellikleri alamayacağınız anlamına gelir. Bunları yalnızca EF5'i .NET 4.5 ile birleştirirken elde edersiniz.

Şimdi Entity Framework 6'ya bir göz atalım. Entity Framework 6'da .NET içinde bulunan çekirdek API'ler artık NuGet paketinin bir parçasıdır.

Anlamı -

  • Tüm Entity Framework, NuGet tarafından dağıtılan bu derlemede yaşıyor

  • Entity Framework enum desteği ve özel veri desteği gibi belirli özellikleri sağlamak için .NET'e bağımlı olmayacaksınız.

  • EF6'nın özelliklerinden birinin, .NET 4 için numaralandırmaları ve uzamsal verileri desteklemesi olduğunu göreceksiniz.

Entity Framework üzerinde çalışmaya başlamak için aşağıdaki geliştirme araçlarını yüklemeniz gerekir -

  • Visual Studio 2013 veya üzeri
  • SQL Server 2012 veya üzeri
  • NuGet Paketinden Entity Framework güncellemeleri

Microsoft, SQL Server'ı da içeren ücretsiz bir görsel stüdyo sürümü sağlar ve www.visualstudio.com adresinden indirilebilir .

Kurulum

Step 1- İndirme tamamlandığında, yükleyiciyi çalıştırın. Aşağıdaki iletişim kutusu görüntülenecektir.

Step 2 - Kur düğmesine tıklayın ve kurulum sürecini başlatacaktır.

Step 3- Kurulum işlemi başarıyla tamamlandıktan sonra aşağıdaki iletişim kutusunu göreceksiniz. Bu iletişim kutusunu kapatın ve gerekirse bilgisayarınızı yeniden başlatın.

Step 4- Aşağıdaki iletişim kutusunu açacak olan Başlat Menüsünden Visual Studio'yu açın. Hazırlık için ilk kez biraz zaman alacak.

Step 5 - Her şey bittiğinde, Visual Studio'nun ana penceresini göreceksiniz.

Dosya → Yeni → Proje'den yeni bir proje oluşturalım

Step 1 - Konsol Uygulaması'nı seçin ve Tamam düğmesine tıklayın.

Step 2 - Çözüm Gezgini'nde projenize sağ tıklayın.

Step 3 - Yukarıdaki görüntüde gösterildiği gibi NuGet Paketlerini Yönet'i seçin, bu, Visual Studio'da aşağıdaki pencereyi açar.

Step 4 - Entity Framework'ü arayın ve en son sürümü yükle düğmesine basarak yükleyin.

Step 5- Tamam'ı tıklayın. Kurulum tamamlandıktan sonra, çıktı Pencerenizde aşağıdaki mesajı göreceksiniz.

Artık başvurunuzu başlatmaya hazırsınız.

Bu eğitimde, basit bir Üniversite veritabanı kullanacağız. Bir Üniversite veritabanı bir bütün olarak çok daha karmaşık olabilir, ancak demo ve öğrenme amacıyla bu veritabanının en basit şeklini kullanıyoruz. Aşağıdaki şema üç tablo içermektedir.

  • Student
  • Course
  • Enrollment

Bir terim veritabanı kullanıldığında, doğrudan aklımıza bir şey gelir ve bu, bir çeşit ilişkisi olan farklı türdeki tablolardır. Tablolar arasında üç tür ilişki vardır ve farklı tablolar arasındaki ilişki, ilgili sütunların nasıl tanımlandığına bağlıdır.

  • Bire Çoğa İlişki
  • Çoktan Çoğa İlişki
  • Bire Bir İlişki

Bire Çoğa İlişki

Bire çok ilişki, en yaygın ilişki türüdür. Bu ilişki türünde, A tablosundaki bir satır, B tablosunda birçok eşleşen satıra sahip olabilir, ancak B tablosundaki bir satır, A tablosunda yalnızca bir eşleşen satıra sahip olabilir. Örneğin, yukarıdaki diyagramda, Öğrenci ve Kayıt tablosunda bir -birçok ilişkiye, her öğrencinin birçok kaydı olabilir, ancak her kayıt yalnızca bir öğrenciye aittir.

Çoktan Çoğa İlişki

Çoktan çoğa bir ilişkide, A tablosundaki bir satır, B tablosunda birçok eşleşen satıra sahip olabilir ve bunun tersi de geçerlidir. Böyle bir ilişki, birincil anahtarı hem tablo A hem de tablo B'deki yabancı anahtarlardan oluşan birleşim tablosu adı verilen üçüncü bir tablo tanımlayarak oluşturursunuz.Örneğin, Öğrenci ve Kurs tablosu, tarafından tanımlanan çoka çok ilişkisine sahiptir. Bu tabloların her birinden Kayıt tablosu ile bire çok ilişkisi.

Bire Bir İlişki

Bire bir ilişkide, A tablosundaki bir satır, B tablosunda birden fazla eşleşen satıra sahip olamaz ve bunun tersi de geçerlidir. İlgili sütunların her ikisi de birincil anahtar ise veya benzersiz kısıtlamalara sahipse, bire bir ilişki oluşturulur.

Bu tür bir ilişki yaygın değildir çünkü bu şekilde ilgili bilgilerin çoğu hepsi bir arada tablo olacaktır. Bire bir ilişki kullanabilirsiniz -

  • Tabloyu çok sayıda sütuna bölün.
  • Güvenlik nedenleriyle bir tablonun bir bölümünü izole edin.
  • Kısa ömürlü ve tabloyu silerek kolayca silinebilecek verileri depolayın.
  • Yalnızca ana tablonun bir alt kümesine uygulanan bilgileri depolayın.

Varlık Veri Modeli (EDM), çeşitli modelleme tekniklerini kullanarak verilerin kavramsal modelini belirleyen Varlık-İlişki modelinin genişletilmiş bir sürümüdür. Aynı zamanda, depolanan biçimine bakılmaksızın veri yapısını tanımlayan bir dizi kavramı ifade eder.

EDM, kavramsal bir modelde özellikleri tanımlayan bir dizi ilkel veri türünü destekler. Entity Framework için temel oluşturan ve toplu olarak Varlık Veri Modeli olarak bilinen 3 temel parçayı dikkate almamız gerekir. Aşağıda EDM'nin üç temel bölümü bulunmaktadır.

  • Depolama Şeması Modeli
  • Kavramsal Model
  • Haritalama Modeli

Depolama Şeması Modeli

Depolama Modeli, Depolama Şeması Tanımlama Katmanı (SSDL) olarak da adlandırılan, arka uç veri deposunun şematik temsilini temsil eder.

Kavramsal Model

Kavramsal Model, aynı zamanda Kavramsal Şema Tanım Katmanı (CSDL) olarak da adlandırılan, sorgularımızı yazdığımız gerçek varlık modelidir.

Haritalama Modeli

Eşleştirme Katmanı, Kavramsal model ile Depolama modeli arasında yalnızca bir eşlemedir.

Mantıksal şema ve fiziksel şema ile eşleştirilmesi bir EDM olarak temsil edilir.

  • Visual Studio ayrıca EDM'nin görsel olarak oluşturulması ve eşleme belirtimi için Varlık Tasarımcısı sağlar.

  • Aracın çıktısı, şemayı ve eşlemeyi belirten XML dosyasıdır (* .edmx).

  • Edmx dosyası Entity Framework meta veri yapılarını içerir.

Şema Tanımlama Dili

ADO.NET Entity Framework, EDM Şemasını tanımlamak için Şema Tanımlama Dili (SDL) adı verilen XML tabanlı bir Veri Tanımlama Dili kullanır.

  • SDL, diğerleri arasında String, Int32, Double, Decimal ve DateTime gibi diğer ilkel türlere benzer Basit Türleri tanımlar.

  • İlkel değerlerin ve adların bir haritasını tanımlayan bir Numaralandırma da basit bir tür olarak kabul edilir.

  • Numaralandırmalar yalnızca 5.0 sürümünden itibaren desteklenir.

  • Karmaşık Türler, diğer türlerin bir araya getirilmesinden oluşturulur. Bu türlerin özelliklerinden oluşan bir koleksiyon bir Varlık Türü tanımlar.

Veri modelinin öncelikle veri yapısını açıklamak için üç temel kavramı vardır:

  • Varlık türü
  • İlişkilendirme türü
  • Property

Varlık Türü

Varlık türü, EDM'deki verilerin yapısını açıklamak için temel yapı taşıdır.

  • Kavramsal bir modelde, varlık türleri özelliklerden oluşturulur ve bir iş uygulamasındaki Öğrenciler ve Kayıtlar gibi üst düzey kavramların yapısını açıklar.

  • Bir varlık, belirli bir Öğrenci veya Kayıt gibi belirli bir nesneyi temsil eder.

  • Her varlık, bir varlık kümesi içinde benzersiz bir varlık anahtarına sahip olmalıdır. Bir varlık kümesi, belirli bir varlık türünün örneklerinin bir koleksiyonudur. Varlık kümeleri (ve ilişkilendirme kümeleri) bir varlık kapsayıcısında mantıksal olarak gruplanır.

  • Devralma varlık türleri ile desteklenir, yani bir varlık türü diğerinden türetilebilir.

İlişkilendirme Türü

EDM'deki ilişkileri tanımlamak için başka bir temel yapı taşıdır. Kavramsal bir modelde, bir ilişki Öğrenci ve Kayıt gibi iki varlık türü arasındaki bir ilişkiyi temsil eder.

  • Her ilişkilendirmenin, ilişkilendirmeye dahil olan varlık türlerini belirten iki ilişkilendirme ucu vardır.

  • Her ilişkilendirme sonu ayrıca, ilişkilendirmenin o ucunda olabilecek varlıkların sayısını gösteren bir ilişkilendirme sonu çokluğunu da belirtir.

  • İlişkilendirme uç çokluğu, bir (1), sıfır veya bir (0..1) veya birçok (*) değerine sahip olabilir.

  • Bir ilişkilendirmenin bir ucundaki varlıklara, gezinme özellikleri aracılığıyla veya bir varlık türünde gösteriliyorlarsa yabancı anahtarlar aracılığıyla erişilebilir.

Emlak

Varlık türleri, yapılarını ve özelliklerini tanımlayan özellikler içerir. Örneğin, bir Öğrenci varlık türünün Öğrenci Kimliği, Adı vb. Gibi özellikleri olabilir.

Bir özellik, ilkel verileri (bir dize, bir tam sayı veya Boole değeri gibi) veya yapılandırılmış verileri (karmaşık bir tür gibi) içerebilir.

Entity Framework, varlıklar olarak bilinen Ortak Dil Çalışma Zamanı (CLR) nesnelerini kullanarak verileri sorgulamanızı, eklemenizi, güncellemenizi ve silmenizi sağlar. Entity Framework, modelinizde tanımlanan varlıkları ve ilişkileri bir veritabanına eşler. Ayrıca şunlar için olanaklar sağlar:

  • Veritabanından döndürülen verileri varlık nesneleri olarak somutlaştırın
  • Nesnelerde yapılan değişiklikleri izleyin
  • Eşzamanlılığı yönetin
  • Nesne değişikliklerini veritabanına geri yay
  • Nesneleri denetimlere bağlama

Verilerle nesneler olarak etkileşimden sorumlu birincil sınıf System.Data.Entity.DbContext'tir. DbContext API, .NET Framework'ün bir parçası olarak yayımlanmamıştır. Entity Framework ekibi, Code First ve DbContext API'ye yeni özellikler yayınlarken daha esnek ve sık olmak için Microsoft'un NuGet dağıtım özelliği aracılığıyla EntityFramework.dll dosyasını dağıtır.

  • NuGet, ilgili DLL'leri Web'den doğrudan projenize çekerek .NET projelerinize başvurular eklemenize olanak tanır.

  • Kitaplık Paket Yöneticisi adlı bir Visual Studio uzantısı, uygun derlemeyi Web'den projelerinize çekmenin kolay bir yolunu sağlar.

  • DbContext API, çoğunlukla Entity Framework ile etkileşiminizi basitleştirmeyi hedeflemektedir.

  • Ayrıca, yaygın olarak kullanılan görevlere erişmek için ihtiyacınız olan yöntem ve özelliklerin sayısını da azaltır.

  • Entity Framework'ün önceki sürümlerinde, bu görevlerin keşfedilmesi ve kodlanması genellikle karmaşıktı.

  • Bağlam sınıfı, nesneleri bir veritabanındaki verilerle doldurmayı, değişiklik izlemeyi ve veritabanına veri kalıcılığını içeren çalışma süresi boyunca varlık nesnelerini yönetir.

DbContext Türetilmiş Sınıfı Tanımlama

Bağlamla çalışmanın önerilen yolu, DbContext'ten türetilen ve bağlamdaki belirtilen varlıkların koleksiyonlarını temsil eden DbSet özelliklerini ortaya çıkaran bir sınıf tanımlamaktır. EF Designer ile çalışıyorsanız, bağlam sizin için oluşturulacaktır. Code First ile çalışıyorsanız, genellikle içeriği kendiniz yazarsınız.

Aşağıdaki kod, UniContext'in DbContext'ten türetildiğini gösteren basit bir örnektir.

  • Alıcı ve ayarlayıcı gibi DbSet ile otomatik özellikleri kullanabilirsiniz.

  • Aynı zamanda çok daha temiz kod yapar, ancak uygulayacak başka bir mantığınız olmadığında bir DbSet oluşturmak amacıyla kullanmanız gerekmez.

public class UniContext : DbContext {
   public UniContext() : base("UniContext") { }
   public DbSet<Student> Students { get; set; }
   public DbSet<Enrollment> Enrollments { get; set; }
   public DbSet<Course> Courses { get; set; }
}
  • Önceden EDM, ObjectContext sınıfından türetilen bağlam sınıfları oluşturmak için kullanılırdı.

  • ObjectContext ile çalışmak biraz karmaşıktı.

  • DbContext, aslında ObjectContext'e benzeyen ve Code First, Model First ve Database First gibi tüm geliştirme modellerinde kullanışlı ve kolay olan ObjectContext etrafında bir sarmalayıcıdır.

Sorguları

Kullanabileceğiniz üç tür sorgu vardır:

  • Yeni bir varlık eklemek.
  • Mevcut bir varlığın özellik değerlerini değiştirme veya güncelleme.
  • Mevcut bir varlığı silme.

Yeni Varlık Ekleme

Entity Framework ile yeni bir nesne eklemek, nesnenizin yeni bir örneğini oluşturmak ve DbSet'teki Add yöntemini kullanarak onu kaydetmek kadar basittir. Aşağıdaki kod, veritabanına yeni bir öğrenci eklemek istediğiniz zamanlar içindir.

private static void AddStudent() {

   using (var context = new UniContext()) {

      var student = new Student {
         LastName = "Khan", 
         FirstMidName = "Ali", 
         EnrollmentDate = DateTime.Parse("2005-09-01") 
      };

      context.Students.Add(student); 
      context.SaveChanges();

   }
}

Mevcut Varlıkları Değiştirme

Mevcut nesneleri değiştirmek, değiştirmek istediğiniz özellik (ler) e atanan değeri güncellemek ve SaveChanges çağırmak kadar basittir. Aşağıdaki kodda Ali'nin soyadı Han iken Aslam olarak değiştirilmiştir.

private static void AddStudent() {

   private static void ChangeStudent() {

      using (var context = new UniContext()) {

         var student = (from d in context.Students
            where d.FirstMidName == "Ali" select d).Single();
         student.LastName = "Aslam";
         context.SaveChanges();

      }
   }
}

Mevcut Varlıkları Silme

Entity Framework kullanarak bir varlığı silmek için, DbSet üzerinde Remove yöntemini kullanırsınız. Hem mevcut hem de yeni eklenen varlıklar için çalışmaları kaldırın. Eklenmiş ancak henüz veritabanına kaydedilmemiş bir varlıkta Remove çağrısı, varlığın eklenmesini iptal edecektir. Varlık, değişiklik izleyiciden kaldırılır ve artık DbContext tarafından izlenmez. Değişiklik izlenen mevcut bir varlıkta Kaldır çağrısı, varlığı bir dahaki sefere SaveChanges çağrıldığında silinmek üzere kaydeder. Aşağıdaki örnek, öğrencinin adı Ali olan veritabanından kaldırıldığı bir örneği gösterir.

private static void DeleteStudent() {

   using (var context = new UniContext()) {
      var bay = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
      context.Students.Remove(bay);
      context.SaveChanges();
   }
}

Entity Framework'te, geliştiricilerin veri sınıflarında herhangi bir değişiklik yapmadan kendi özel veri sınıflarını veri modeliyle birlikte kullanmalarına olanak tanıyan iki tür varlık vardır.

  • POCO varlıkları
  • Dinamik Proxy

POCO Varlıkları

  • POCO, veri modelinizle mevcut etki alanı nesneleri olarak kullanılabilen "düz eski" CLR nesneleri anlamına gelir.

  • Varlıklarla eşlenen POCO veri sınıfları bir veri modelinde tanımlanır.

  • Ayrıca Varlık Veri Modeli araçları tarafından oluşturulan varlık türleri olarak aynı sorgu, ekleme, güncelleme ve silme davranışlarının çoğunu destekler.

  • Kavramsal bir modelden kalıcılık açısından cahil varlık türleri oluşturmak için POCO şablonunu kullanabilirsiniz.

Aşağıdaki Kavramsal Varlık Veri Modeli örneğine bir göz atalım.

Yukarıdaki Varlık modeli için POCO varlıkları oluşturmak için -

Step 1- Tasarımcı penceresine sağ tıklayın. Aşağıdaki iletişim kutusunu gösterecektir.

Step 2 - Kod Oluşturma Öğesi Ekle öğesini seçin ...

Step 3 - EF 6.x DbContext Üreticisini seçin, adı yazın ve ardından Ekle düğmesine tıklayın.

Çözüm gezgininizde POCODemo.Context.tt ve POCODemo.tt şablonlarının üretildiğini göreceksiniz.

POCODemo.Context, DbContext'i ve geri dönüp sorgulama için kullanabileceğiniz, örneğin bağlam, Öğrenciler ve Kurslar vb. İçin kullanabileceğiniz nesne kümelerini oluşturur.

Diğer şablon, Öğrenci, Kurslar, vb. Tüm türlerle ilgilidir. Aşağıda, Varlık Modeli'nden otomatik olarak oluşturulan Öğrenci sınıfı kodu verilmiştir.

namespace ConsoleApplication1 {

   using System;
   using System.Collections.Generic;

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         CA2227:CollectionPropertiesShouldBeReadOnly")]

      public virtual ICollection<Enrollment> Enrollments { get; set; }

   }
}

Varlık Modelinden Ders ve Kayıt tabloları için benzer sınıflar oluşturulur.

Dinamik Proxy

POCO varlık türlerinin örneklerini oluştururken, Entity Framework genellikle varlık için bir proxy görevi gören dinamik olarak oluşturulmuş bir türetilmiş türün örneklerini oluşturur. BT'nin, POCO varlığının bir sarmalayıcı sınıfı gibi bir çalışma zamanı proxy sınıfı olduğu da söylenebilir.

  • Özelliğe erişildiğinde otomatik olarak eylemler gerçekleştirmek için varlığın bazı özelliklerini geçersiz kılabilirsiniz.

  • Bu mekanizma, ilişkilerin tembel yüklenmesini ve otomatik değişiklik takibini desteklemek için kullanılır.

  • Bu teknik, Code First ve EF Designer ile oluşturulan modeller için de geçerlidir.

Entity Framework'ün ilgili nesnelerin geç yüklenmesini desteklemesini ve POCO sınıflarındaki değişiklikleri izlemesini istiyorsanız, POCO sınıflarının aşağıdaki gereksinimleri karşılaması gerekir:

  • Özel veri sınıfı, genel erişimle beyan edilmelidir.

  • Özel veri sınıfı mühürlenmemelidir.

  • Özel veri sınıfı soyut olmamalıdır.

  • Özel veri sınıfı, parametreleri olmayan genel veya korumalı bir oluşturucuya sahip olmalıdır.

  • CreateObject yönteminin POCO varlığı için bir proxy oluşturmak üzere kullanılmasını istiyorsanız, parametresiz korumalı bir kurucu kullanın.

  • CreateObject yönteminin çağrılması, proxy oluşturulmasını garanti etmez: POCO sınıfı, bu konuda açıklanan diğer gereksinimleri takip etmelidir.

  • Proxy sınıfları bu arabirimleri uyguladığından, sınıf IEntityWithChangeTracker veya IEntityWithRelationships arabirimlerini uygulayamaz.

  • ProxyCreationEnabled seçeneği true olarak ayarlanmalıdır.

Aşağıdaki örnek, dinamik vekil varlık sınıfına aittir.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Proxy nesneleri oluşturmayı devre dışı bırakmak için ProxyCreationEnabled özelliğinin değerini false olarak ayarlayın.

İlişkisel veritabanlarında ilişki, ilişkisel veritabanı tabloları arasında yabancı anahtarlar aracılığıyla var olan bir durumdur. Yabancı Anahtar (FK), iki tablodaki veriler arasında bir bağlantı kurmak ve uygulamak için kullanılan bir sütun veya sütunların birleşimidir. Aşağıdaki şema üç tablo içermektedir.

  • Student
  • Course
  • Enrollment

Yukarıdaki diyagramda, tablolar arasında bir tür ilişki / ilişki görebilirsiniz. Tablolar arasında üç tür ilişki vardır ve farklı tablolar arasındaki ilişki, ilgili sütunların nasıl tanımlandığına bağlıdır.

  • Bire Çoğa İlişki
  • Çoktan Çoğa İlişki
  • Bire Bir İlişki

Bire Çoğa İlişki

  • Bire çok ilişki, en yaygın ilişki türüdür.

  • Bu ilişki türünde, A tablosundaki bir satır, B tablosunda birçok eşleşen satıra sahip olabilir, ancak B tablosundaki bir satır, A tablosunda yalnızca bir eşleşen satıra sahip olabilir.

  • Yabancı anahtar, ilişkinin birçok sonunu temsil eden tabloda tanımlanır.

  • Örneğin, yukarıdaki diyagramda Öğrenci ve Kayıt tabloları bire bir ilişkiye sahiptir, her öğrencinin birçok kaydı olabilir, ancak her kayıt yalnızca bir öğrenciye aittir.

Varlık çerçevesinde bu ilişkiler kod ile de oluşturulabilir. Aşağıda, bire çok ilişki ile ilişkilendirilmiş Öğrenci ve Kayıt sınıflarının bir örneği bulunmaktadır.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Enrollment {

   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
	
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

Yukarıdaki kodda, Öğrenci sınıfının Kayıt koleksiyonunu içerdiğini, ancak Kayıt sınıfının tek bir Öğrenci Nesnesine sahip olduğunu görebilirsiniz.

Çoktan Çoğa İlişki

Çoktan çoğa ilişkisinde, A tablosundaki bir satır, B tablosunda birçok eşleşen satıra sahip olabilir ve bunun tersi de geçerlidir.

  • Bu tür bir ilişki, birincil anahtarı hem tablo A hem de tablo B'deki yabancı anahtarlardan oluşan bağlantı tablosu adı verilen üçüncü bir tablo tanımlayarak oluşturabilirsiniz.

  • Örneğin, Öğrenci ve Kurs tabloları, bu tabloların her birinden Kayıt tablosuna bire çok ilişkisiyle tanımlanan çoka çok ilişkisine sahiptir.

Aşağıdaki kod, Course sınıfını ve yukarıdaki iki sınıfı içerir, yani, Student ve Enrollment.

public class Course {
   [DatabaseGenerated(DatabaseGeneratedOption.None)]
	
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; } 
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Hem Course sınıfının hem de Öğrenci sınıfının junction class Enrollment aracılığıyla çoktan çoğa ilişki kuran Kayıt nesneleri koleksiyonlarına sahip olduğunu görebilirsiniz.

Bire Bir İlişki

  • Bire bir ilişkide, A tablosundaki bir satır, B tablosunda birden fazla eşleşen satıra sahip olamaz ve bunun tersi de geçerlidir.

  • İlgili sütunların her ikisi de birincil anahtar ise veya benzersiz kısıtlamalara sahipse, bire bir ilişki oluşturulur.

  • Bire bir ilişkide, birincil anahtar ek olarak yabancı anahtar görevi görür ve her iki tablo için ayrı yabancı anahtar sütunu yoktur.

Bu tür bir ilişki yaygın değildir çünkü bu şekilde ilişkili çoğu bilgi tek bir tabloda olacaktır. Bire bir ilişki kullanabilirsiniz -

  • Tabloyu çok sayıda sütuna bölün.
  • Güvenlik nedenleriyle bir tablonun bir bölümünü izole edin.
  • Kısa ömürlü ve tabloyu silerek kolayca silinebilecek verileri depolayın.
  • Yalnızca ana tablonun bir alt kümesine uygulanan bilgileri depolayın.

Aşağıdaki kod, öğrenci e-posta kimliğini ve şifresini içeren başka bir sınıf adı StudentProfile eklemektir.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
   public virtual StudentProfile StudentProfile { get; set; }
}

public class StudentProfile {

   public StudentProfile() {}
   public int ID { get; set; }
   public string Email { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Student varlık sınıfının StudentProfile gezinme özelliğini ve StudentProfile öğesinin Student gezinme özelliğini içerdiğini görebilirsiniz.

Her öğrencinin üniversite alanında oturum açmak için yalnızca bir E-posta adresi ve şifresi vardır. Bu bilgiler Öğrenci tablosuna eklenebilir ancak güvenlik nedeniyle başka bir tabloya ayrılmıştır.

Ömür

Bir bağlamın ömrü, örnek oluşturulduğunda başlar ve örnek atıldığında veya çöpte toplandığında sona erer.

  • Bağlam ömrü, ORM'leri kullandığımızda vermemiz gereken çok önemli bir karardır.

  • Bağlam, bir varlık önbelleği gibi performans gösteriyor, bu nedenle bellek tüketiminde çok hızlı büyüyebilen ve ayrıca bellek sızıntılarına neden olabilecek tüm yüklü varlıklara referanslar tuttuğu anlamına gelir.

  • Aşağıdaki şemada, Bağlam aracılığıyla uygulamadan veritabanına ve tam tersi veri iş akışının üst düzeyini görebilirsiniz.

Varlık Yaşam Döngüsü

Varlık Yaşam Döngüsü, bir Varlığın oluşturulduğu, eklendiği, değiştirildiği, silindiği vb. Süreci açıklar. Varlıkların yaşam süreleri boyunca birçok durumu vardır. Varlık durumunun nasıl alınacağına bakmadan önce, varlık durumunun ne olduğuna bir göz atalım. Devlet bir tür listesiSystem.Data.EntityState aşağıdaki değerleri bildiren -

  • Added: Varlık eklendi olarak işaretlenir.

  • Deleted: Varlık, silinmiş olarak işaretlenmiştir.

  • Modified: Varlık değiştirildi.

  • Unchanged: Varlık değiştirilmedi.

  • Detached: Varlık izlenmez.

Varlık Yaşam Döngüsündeki Durum Değişiklikleri

Bazen varlıkların durumu bağlam tarafından otomatik olarak belirlenir, ancak geliştirici tarafından manuel olarak da değiştirilebilir. Bir durumdan diğerine geçişlerin tüm kombinasyonları mümkün olsa da, bazıları anlamsızdır. Örneğin,Added varlık Deleted devlet veya tam tersi.

Farklı durumlar hakkında tartışalım.

Değişmemiş Durum

  • Bir varlık Değiştirilmediğinde, bağlama bağlıdır ancak değiştirilmemiştir.

  • Varsayılan olarak, veritabanından alınan bir varlık bu durumdadır.

  • Bir varlık bağlama eklendiğinde (İliştirme yöntemiyle), benzer şekilde Değiştirilmemiş durumdadır.

  • Bağlam, referans göstermediği nesnelerdeki değişiklikleri izleyemez, bu nedenle eklendiğinde, Değişmemiş olduklarını varsayar.

Müstakil Devlet

  • Ayrılmış, yeni oluşturulan bir varlığın varsayılan durumudur çünkü bağlam, kodunuzdaki herhangi bir nesnenin oluşturulmasını izleyemez.

  • Varlığı bağlamın bir bloğunun içinde başlatsanız bile bu doğrudur.

  • Ayrılmış, izleme devre dışı bırakıldığında veritabanından alınan varlıkların durumudur.

  • Bir varlık ayrıldığında içeriğe bağlı değildir, dolayısıyla durumu izlenmez.

  • Elden çıkarılabilir, değiştirilebilir, diğer sınıflarla birlikte kullanılabilir veya ihtiyacınız olabilecek başka herhangi bir şekilde kullanılabilir.

  • Bunu izleyen bir bağlam olmadığından, Entity Framework için bir anlamı yoktur.

Eyalet eklendi

  • Bir varlık Eklendi durumunda olduğunda, birkaç seçeneğiniz vardır. Aslında, onu yalnızca bağlamdan ayırabilirsiniz.

  • Doğal olarak, bazı özellikleri değiştirseniz bile, durum Eklenmiş olarak kalır, çünkü onu Değiştirilmiş, Değiştirilmemiş veya Silinmiş olarak taşımak anlamsızdır.

  • Bu yeni bir varlıktır ve veri tabanındaki bir satırla uyuşmaz.

  • Bu, bu durumlardan birinde olmak için temel bir ön koşuldur (ancak bu kural bağlam tarafından uygulanmaz).

Değiştirilmiş Durum

  • Bir varlık değiştirildiğinde, bu onun Değiştirilmemiş durumda olduğu ve ardından bazı özelliklerin değiştirildiği anlamına gelir.

  • Bir varlık Değiştirilmiş durumuna girdikten sonra Ayrılmış veya Silinmiş durumuna geçebilir, ancak orijinal değerleri manuel olarak geri yükleseniz bile Değiştirilmedi durumuna geri dönemez.

  • Varlığı bağlamdan ayırıp eklemediğiniz sürece Eklendi olarak bile değiştirilemez, çünkü bu kimliğe sahip bir satır veritabanında zaten mevcuttur ve devam ettirirken bir çalışma zamanı istisnası alırsınız.

Eyalet Silindi

  • Bir varlık, Değiştirilmemiş veya Değiştirilmiş olduğundan Silinmiş durumuna girer ve ardından DeleteObject yöntemi kullanılmıştır.

  • Bu en kısıtlayıcı durumdur, çünkü bu durumdan Müstakil dışında başka bir değere geçiş anlamsızdır.

usingbağlamın kontrol ettiği tüm kaynakların bloğun sonunda atılmasını istiyorsanız. Kullandığınızdausing deyimi, ardından derleyici otomatik olarak bir try / nih bloğu oluşturur ve nihayet bloğunda dispose çağırır.

using (var context = new UniContext()) {

   var student = new Student {
      LastName = "Khan", 
      FirstMidName = "Ali", 
      EnrollmentDate = DateTime.Parse("2005-09-01")
   };

   context.Students.Add(student);
   context.SaveChanges();
}

Uzun süreli bağlamla çalışırken aşağıdakileri göz önünde bulundurun -

  • Belleğe daha fazla nesne ve bunların referanslarını yükledikçe, bağlamın bellek tüketimi hızla artabilir. Bu, performans sorunlarına neden olabilir.

  • Artık gerekli olmadığında bağlamı elden çıkarmayı unutmayın.

  • Bir istisna, içeriğin kurtarılamaz bir durumda olmasına neden olursa, uygulamanın tamamı sona erebilir.

  • Verilerin sorgulandığı ve güncellendiği zaman arasındaki boşluk büyüdükçe eşzamanlılıkla ilgili sorunlara rastlama şansı artar.

  • Web uygulamalarıyla çalışırken, istek başına bir bağlam örneği kullanın.

  • Windows Presentation Foundation (WPF) veya Windows Forms ile çalışırken, form başına bir bağlam örneği kullanın. Bu, içeriğin sağladığı değişiklik izleme işlevini kullanmanıza olanak tanır.

Başparmak Kuralları

Web Applications

  • Web uygulamaları için her istek için bağlamın kullanılması artık yaygın ve en iyi uygulamadır.

  • Web uygulamalarında, çok kısa olan ancak tüm sunucu işlemlerini tutan isteklerle ilgileniriz, bu nedenle bağlamın içinde yaşaması için uygun süre.

Desktop Applications

  • Win Forms / WPF, vb. Gibi masaüstü uygulamaları için bağlam, form / iletişim kutusu / sayfa başına kullanılır.

  • Bağlamın uygulamamız için bir tekil olarak olmasını istemediğimizden, bir formdan diğerine geçerken onu elden çıkaracağız.

  • Bu şekilde, bağlamın birçok yeteneğini kazanacağız ve uzun süreli bağlamların sonuçlarından zarar görmeyeceğiz.

Entity Framework, bir varlık modeli oluşturmak için üç yaklaşım sağlar ve her birinin kendi artıları ve eksileri vardır.

  • Önce Kod
  • Önce Veritabanı
  • Önce Model

Bu bölümde, kod ilk yaklaşımını kısaca açıklayacağız. Bazı geliştiriciler Kodda Tasarımcı ile çalışmayı tercih ederken, diğerleri sadece kodlarıyla çalışmayı tercih eder. Bu geliştiriciler için Entity Framework, Code First olarak adlandırılan bir modelleme iş akışına sahiptir.

  • Code First modelleme iş akışı, var olmayan bir veritabanını hedefler ve Code First onu oluşturur.

  • Ayrıca boş bir veritabanınız varsa kullanılabilir ve ardından Code First yeni tablolar da ekleyecektir.

  • Code First, modelinizi C # veya VB.Net sınıflarını kullanarak tanımlamanıza olanak tanır.

  • Ek yapılandırma, isteğe bağlı olarak sınıflarınız ve özelliklerinizdeki öznitelikler kullanılarak veya akıcı bir API kullanılarak gerçekleştirilebilir.

Neden Önce Kod?

  • Code First gerçekten bir dizi bulmaca parçasından oluşuyor. Öncelikle alan sınıflarınız.

  • Etki alanı sınıflarının Entity Framework ile ilgisi yoktur. Bunlar yalnızca işletme alanınızın öğeleridir.

  • Entity Framework, daha sonra, bu sınıflar ve veritabanınız arasındaki etkileşimi yöneten bir bağlama sahiptir.

  • Bağlam, Code First'e özgü değildir. Bir Entity Framework özelliğidir.

  • Code First, bağlamın yönettiği sınıflarınızı inceleyen bir model oluşturucu ekler ve ardından bu sınıfların ve ilişkilerin bir modeli nasıl tanımladığını ve bu modelin veritabanınızla nasıl eşleneceğini belirlemek için bir dizi kural veya kural kullanır.

  • Tüm bunlar çalışma zamanında gerçekleşir. Bu modeli asla görmeyeceksiniz, sadece hafızada.

  • Code First, gerekirse bir veritabanı oluşturmak için bu modeli kullanma yeteneğine sahiptir.

  • Ayrıca, model değişirse, Code First Migrations adlı bir özelliği kullanarak veritabanını güncelleyebilir.

Bu bölümde, Model First olarak adlandırılan iş akışını kullanarak tasarımcıda bir varlık veri modelinin nasıl oluşturulacağını öğrenelim.

  • Model First, veritabanının henüz var olmadığı yeni bir projeye başladığınızda harikadır.

  • Model bir EDMX dosyasında saklanır ve Entity Framework Designer'da görüntülenebilir ve düzenlenebilir.

  • Model First'te, modelinizi bir Entity Framework tasarımcısında tanımlar, ardından modelinizle eşleşecek veritabanı şeması oluşturan SQL'i oluşturur ve ardından veritabanınızda şemayı oluşturmak için SQL'i çalıştırırsınız.

  • Uygulamanızda etkileşim kurduğunuz sınıflar otomatik olarak EDMX dosyasından oluşturulur.

Aşağıda Model First yaklaşımını kullanarak yeni bir konsol projesi oluşturmanın basit bir örneği verilmiştir.

Step 1 - Visual Studio'yu açın ve Dosya → Yeni → Proje'yi seçin

Step 2 - Sol bölmeden Yüklü → Şablonlar → Görsel C # → Pencereler'i seçin ve ardından orta bölmede Konsol Uygulaması'nı seçin.

Step 3 - Ad alanına EFModelFirstDemo yazın.

Step 4 - Model oluşturmak için önce çözüm gezgininde konsol projenize sağ tıklayın ve Ekle → Yeni Öğeler… öğesini seçin.

Aşağıdaki iletişim kutusu açılacaktır.

Step 5 - Orta bölmeden ADO.NET Varlık Veri Modeli'ni seçin ve Ad alanına ModelFirstDemoDB adını girin.

Step 6 - Varlık Veri Modeli Sihirbazı iletişim kutusunu başlatacak Ekle düğmesine tıklayın.

Step 7- Boş EF Designer modelini seçin ve İleri düğmesine tıklayın. Entity Framework Designer, boş bir modelle açılır. Şimdi modele varlıklar, özellikler ve ilişkilendirmeler eklemeye başlayabiliriz.

Step 8- Tasarım yüzeyine sağ tıklayın ve Özellikler'i seçin. Özellikler penceresinde, Varlık Kapsayıcı Adı'nı ModelFirstDemoDBContext olarak değiştirin.

Step 9 - Tasarım yüzeyine sağ tıklayın ve Yeni → Varlık Ekle… öğesini seçin.

Varlık Ekle iletişim kutusu aşağıdaki resimde gösterildiği gibi açılacaktır.

Step 10 - Varlık adı olarak Öğrenci ve mülk adı olarak Öğrenci Kimliği girin ve Tamam'ı tıklayın.

Step 11 - Tasarım yüzeyinde yeni varlığa sağ tıklayın ve Yeni Ekle → Skaler Özellik öğesini seçin, özellik adı olarak Ad girin.

Step 12 - FirstName girin ve ardından LastName ve EnrollmentDate gibi iki skaler özellik daha ekleyin.

Step 13 - Yukarıda belirtilen tüm adımları izleyerek iki tane daha Varlık Kursu ve Kayıt ekleyin ve ayrıca aşağıdaki adımlarda gösterildiği gibi bazı Skaler özellikler ekleyin.

Step 14 - Visual Designer'da üç varlığımız var, aralarına bir miktar ilişki veya ilişki ekleyelim.

Step 15 - Tasarım yüzeyine sağ tıklayın ve Yeni → İlişkilendirme Ekle… öğesini seçin.

Step 16 - İlişkinin bir ucunu Öğrenci'ye, diğer ucunu da çok sayıda çok sayıda Kayıt'a işaret edin.

Step 17 - Bu, bir Öğrencinin birçok Kaydı olduğu ve Kaydın bir Öğrenciye ait olduğu anlamına gelir.

Step 18 - 'Varlığı Gönder' öğesine yabancı anahtar özellikleri ekle kutusunun işaretli olduğundan emin olun ve Tamam'ı tıklayın.

Step 19 - Benzer şekilde, Kurs ve Kayıt arasında bir ilişki daha ekleyin.

Step 20 - Varlıklar arasında ilişkilendirmeler ekledikten sonra veri modeliniz aşağıdaki ekran gibi görünecektir.

Artık bir veritabanı oluşturabileceğimiz ve verileri okumak ve yazmak için kullanabileceğimiz basit bir modelimiz var. Devam edelim ve veritabanını oluşturalım.

Step 1 - Tasarım yüzeyine sağ tıklayın ve Modelden Veritabanı Oluştur'u seçin ...

Step 2 - Mevcut veritabanını seçebilir veya Yeni Bağlantı… seçeneğine tıklayarak yeni bir bağlantı oluşturabilirsiniz.

Step 3 - Yeni Veritabanı oluşturmak için Yeni Bağlantı'ya tıklayın…

Step 4 - Sunucu adını ve veritabanı adını girin.

Step 5 - İleri'yi tıklayın.

Step 6- Bitir'i tıklayın. Bu, projeye * .edmx.sql dosyasını ekleyecektir. .Sql dosyasını açıp ardından sağ tıklayıp Yürüt'ü seçerek Visual Studio'da DDL betiklerini yürütebilirsiniz.

Step 7 - Veritabanına bağlanmak için aşağıdaki iletişim kutusu görüntülenecektir.

Step 8 - Başarılı yürütmede, aşağıdaki mesajı göreceksiniz.

Step 9 - Sunucu gezginine gidin, veritabanının belirtilen üç tabloyla oluşturulduğunu göreceksiniz.

Ardından, DbContext API'sini kullanan kod üretmek için modelimizi değiştirmemiz gerekiyor.

Step 1 - EF Designer'da modelinizin boş bir noktasına sağ tıklayın ve Kod Oluşturma Öğesi Ekle… öğesini seçin.

Aşağıdaki Yeni Öğe Ekle iletişim kutusunun açıldığını göreceksiniz.

Step 2 - Orta bölmede EF 6.x DbContext Generator öğesini seçin ve Name alanına ModelFirstDemoModel girin.

Step 3 - Çözüm gezgininizde ModelFirstDemoModel.Context.tt ve ModelFirstDemoModel.tt şablonlarının oluşturulduğunu göreceksiniz.

ModelFirstDemoModel.Context, DbCcontext ve geri dönüp sorgulama için kullanabileceğiniz nesne kümelerini oluşturur, örneğin bağlam, Öğrenciler ve Kurslar vb.

Diğer şablon, Öğrenci, Kurslar vb. Tüm türlerle ilgilidir. Aşağıda, Varlık Modeli'nden otomatik olarak oluşturulan Öğrenci sınıfı yer almaktadır.

Aşağıda bazı verilerin girildiği ve veritabanından alındığı C # kodu verilmiştir.

using System;
using System.Linq;

namespace EFModelFirstDemo {

   class Program {

      static void Main(string[] args) {

         using (var db = new ModelFirstDemoDBContext()) {

            // Create and save a new Student

            Console.Write("Enter a name for a new Student: ");
            var firstName = Console.ReadLine();

            var student = new Student {
               StudentID = 1,
               FirstName = firstName
            };
				
            db.Students.Add(student);
            db.SaveChanges();
				
            var query = from b in db.Students
               orderby b.FirstName select b;

            Console.WriteLine("All student in the database:");

            foreach (var item in query) {
               Console.WriteLine(item.FirstName);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
         }
      }
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

Enter a name for a new Student:
Ali Khan
All student in the database:
Ali Khan
Press any key to exit...

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bu bölümde, Database First yaklaşımıyla bir varlık veri modeli oluşturmayı öğrenelim.

  • Database First Approach, Entity Data Modeline Code First ve Model First yaklaşımlarına bir alternatif sağlar. Projedeki veritabanından model kodları (sınıflar, özellikler, DbContext vb.) Oluşturur ve bu sınıflar veritabanı ile denetleyici arasındaki bağlantı haline gelir.

  • Veritabanı İlk Yaklaşımı, var olan bir veritabanından varlık çerçevesini oluşturur. Model / veritabanı senkronizasyonu ve kod oluşturma gibi diğer tüm işlevleri, Model First yaklaşımında kullandığımız şekilde kullanırız.

Basit bir örnek verelim. Aşağıdaki resimde gösterildiği gibi 3 tabloyu içeren bir veritabanımız zaten var.

Step 1 - DatabaseFirstDemo adı ile yeni bir konsol projesi oluşturalım.

Step 2 - Modeli oluşturmak için, önce çözüm gezgininde konsol projenize sağ tıklayın ve Ekle → Yeni Öğeler… öğesini seçin.

Step 3 - Orta bölmeden ADO.NET Varlık Veri Modeli'ni seçin ve Ad alanına DatabaseFirstModel adını girin.

Step 4 - Varlık Veri Modeli Sihirbazı iletişim kutusunu başlatacak Ekle düğmesine tıklayın.

Step 5 - Veritabanından EF Designer'ı seçin ve İleri düğmesine tıklayın.

Step 6 - Mevcut veritabanını seçin ve İleri'ye tıklayın.

Step 7 - Entity Framework 6.x'i seçin ve İleri'ye tıklayın.

Step 8 - Dahil etmek istediğiniz tüm tablo Görünümlerini ve saklı yordamı seçin ve Son'u tıklayın.

Varlık modelinin ve POCO sınıflarının veritabanından oluşturulduğunu göreceksiniz.

Şimdi program.cs dosyasına aşağıdaki kodu yazarak tüm öğrencileri veritabanından alalım.

using System;
using System.Linq;

namespace DatabaseFirstDemo {

   class Program {

      static void Main(string[] args) {

         using (var db = new UniContextEntities()) {

            var query = from b in db.Students
               orderby b.FirstMidName select b;

            Console.WriteLine("All All student in the database:");

            foreach (var item in query) {
               Console.WriteLine(item.FirstMidName +" "+ item.LastName);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
         }
      }
   }
}

Yukarıdaki program yürütüldüğünde, aşağıdaki çıktıyı alacaksınız -

All student in the database:
Ali Khan
Arturo   finand
Bill Gates
Carson Alexander
Gytis Barzdukas
Laura Norman
Meredith Alonso
Nino Olivetto
Peggy Justice
Yan Li
Press any key to exit...

Yukarıdaki program yürütüldüğünde, daha önce veri tabanına girilmiş olan tüm öğrencilerin adını göreceksiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bu bölümde, Designer veya Database First ile veya sadece Code First kullanarak modeller oluşturmaya odaklanalım. Aşağıda, hangi modelleme iş akışını seçeceğinize karar vermenize yardımcı olacak bazı yönergeler verilmiştir.

  • Code First modelleme, Database First modelleme ve Model First modelleme iş akışının örneklerini daha önce görmüştük.

  • Database First ve Model First iş akışları Tasarımcıyı kullanır, ancak biri model oluşturmak için veritabanıyla başlar ve diğeri modelde bir veritabanı oluşturmak için başlar.

  • Visual Designer artı kod oluşturmayı kullanmak istemeyen geliştiriciler için Entity Framework, Code First adında tamamen farklı bir iş akışına sahiptir.

  • Code First için tipik iş akışı, veritabanınızın bile olmadığı yepyeni uygulamalar için mükemmeldir. Sınıflarınızı ve kodunuzu tanımlarsınız ve ardından Code First'ün veritabanınızın nasıl görünmesi gerektiğini anlamasına izin verirsiniz.

  • Code First'ü bir veritabanıyla başlatmak da mümkündür ve bu Code First'ü biraz çelişki haline getirir. Ancak bir veritabanını sınıflara göre tersine çevirmenize izin veren bir araç var, bu da kodlamaya bir adım önde başlamak için harika bir yoldur.

Bu seçenekler göz önüne alındığında, Karar Ağacına bakalım.

  • Oluşturulan kodda bir Visual Designer ile çalışmayı tercih ediyorsanız, EF Designer içeren iş akışlarından birini seçmek isteyeceksiniz. Veritabanınız zaten varsa, Veritabanı Önce sizin yolunuzdur.

  • Veritabanı olmadan yepyeni bir projede bir Görsel Tasarımcı kullanmak istiyorsanız, Model First'ü kullanmak isteyeceksiniz.

  • Bir Tasarımcı ile değil, yalnızca kodla çalışmak istiyorsanız, Code First, veritabanını sınıflara tersine çeviren aracı kullanma seçeneğiyle birlikte muhtemelen sizin içindir.

  • Mevcut sınıflarınız varsa, yapabileceğiniz en iyi şey onları Code First ile kullanmaktır.

Önceki bölümlerde, bir varlık veri modelini tanımlamanın üç farklı yolunu öğrendiniz.

  • Bunlardan ikisi, Database First ve Model First, kod oluşturma ile birlikte Entity Framework tasarımcısına bağlıdır.

  • Üçüncüsü, Code First, görsel bir tasarımcıyı atlamanıza ve sadece kendi kodunuzu yazmanıza izin verir.

  • Hangi yolu seçerseniz seçin, etki alanı sınıfları elde edersiniz ve bir veya daha fazla Entity Framework DbContext sınıfı, bu sınıflarla ilgili verileri almanıza ve sürdürmenize olanak tanır.

Uygulamalarınızdaki DbContext API, sınıflarınız ve veritabanınız arasında bir köprü olarak kullanılır. DbContext, Entity Framework'teki en önemli sınıflardan biridir.

  • Sorguların ifade edilmesini ve yürütülmesini sağlar.

  • Veritabanından sorgu sonuçlarını alır ve bunları model sınıflarımızın örneklerine dönüştürür.

  • Ekleme ve silme dahil varlıklarda yapılan değişiklikleri takip edebilir ve ardından talep üzerine veritabanına gönderilen insert, update ve delete ifadelerinin oluşturulmasını tetikler.

Aşağıda, bu bölümde farklı işlemler gerçekleştireceğimiz etki alanı reklam bağlamı sınıfları verilmiştir. Bu, Database First Approach adlı bölümde oluşturduğumuz örnekle aynıdır.

Bağlam Sınıfı Uygulaması

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

namespace DatabaseFirstDemo {

   public partial class UniContextEntities : DbContext {

      public UniContextEntities(): base("name = UniContextEntities") {}

      protected override void OnModelCreating(DbModelBuilder modelBuilder) {
         throw new UnintentionalCodeFirstException();
      }

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }
}

Alan Sınıfları Uygulaması

Kurs sınıfı

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic;
	
   public partial class Course {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Course() {
         this.Enrollments = new HashSet<Enrollment>();
      }
	
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
	
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Öğrenci sınıfı

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Kayıt sınıfı

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Enrollment {

      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Nullable<int> Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }
}

İşlem Oluştur

Entity Framework ile yeni bir nesne eklemek, nesnenizin yeni bir örneğini oluşturmak ve DbSet'teki Add yöntemini kullanarak onu kaydetmek kadar basittir. Aşağıdaki kod, veritabanına yeni bir öğrenci eklemenizi sağlar.

class Program {

   static void Main(string[] args) {

      var newStudent = new Student();

      //set student name

      newStudent.FirstMidName = "Bill";
      newStudent.LastName = "Gates";
      newStudent.EnrollmentDate = DateTime.Parse("2015-10-21");
      newStudent.ID = 100;

      //create DBContext object

      using (var dbCtx = new UniContextEntities()) {

         //Add Student object into Students DBset
         dbCtx.Students.Add(newStudent);

         // call SaveChanges method to save student into database
         dbCtx.SaveChanges();
      }
   }
}

Güncelleme İşlemi

Mevcut nesneleri değiştirmek, değiştirmek istediğiniz özellik (ler) e atanan değeri güncellemek ve SaveChanges çağırmak kadar basittir. Örneğin, Ali'nin soyadını Khan'dan Aslam olarak değiştirmek için aşağıdaki kod kullanılır.

using (var context = new UniContextEntities()) {

   var student = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   student.LastName = "Aslam";
   context.SaveChanges();
}

İşlemi Sil

Entity Framework kullanarak bir varlığı silmek için, DbSet üzerinde Remove yöntemini kullanırsınız. Hem mevcut hem de yeni eklenen varlıklar için çalışmaları kaldırın. Eklenmiş ancak henüz veritabanına kaydedilmemiş bir varlıkta Remove çağrısı, varlığın eklenmesini iptal edecektir. Varlık, değişiklik izleyiciden kaldırılır ve artık DbContext tarafından izlenmez. Değişiklik izlenen mevcut bir varlıkta Kaldır çağrısı, varlığı bir dahaki sefere SaveChanges çağrıldığında silinmek üzere kaydeder. Aşağıdaki örnek, öğrencinin adı Ali olan veritabanından kaldırıldığı bir koddur.

using (var context = new UniContextEntities()) {
   var bay = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   context.Students.Remove(bay);
   context.SaveChanges();
}

İşlemi Oku

Mevcut verileri veritabanından okumak çok basittir. Aşağıda, Öğrenci tablosundaki tüm verilerin alındığı ve ardından alfabetik sırayla öğrencilerin adı ve soyadı ile bir program görüntüleneceği kod bulunmaktadır.

using (var db = new UniContextEntities()) {

   var query = from b in db.Students orderby b.FirstMidName select b;
   Console.WriteLine("All All student in the database:");

   foreach (var item in query) {
      Console.WriteLine(item.FirstMidName +" "+ item.LastName);
   }

   Console.WriteLine("Press any key to exit...");
   Console.ReadKey();
}

Herhangi bir veri erişimi geliştiricisi, veri eşzamanlılığı ile ilgili "Aynı anda birden fazla kişi aynı verileri düzenlerse ne olur?"

  • Aramızdan daha şanslı olanlar, "sorun yok, sonuncusu kazanır" diyen iş kurallarıyla uğraşır.

  • Bu durumda eşzamanlılık bir sorun değildir. Büyük olasılıkla, bu kadar basit değil ve her senaryoyu aynı anda çözecek sihirli bir değnek yok.

  • Varsayılan olarak, Entity Framework "sonuncusu kazanır" yolunu alacaktır, bu, verinin alındığı ve kaydedildiği zaman arasındaki verileri başka biri güncellese bile en son güncellemenin uygulanacağı anlamına gelir.

Daha iyi anlamak için bir örnek alalım. Aşağıdaki örnek, Kurs tablosuna yeni bir sütun VersionNo ekler.

Tasarımcıya gidin ve tasarımcı penceresine sağ tıklayın ve veritabanından güncel modeli seçin ...

Kurs Varlığına başka bir sütunun eklendiğini göreceksiniz.

Yeni oluşturulan VersionNo sütununa sağ tıklayın ve Özellikler'i seçin ve aşağıdaki görüntüde gösterildiği gibi Eş Zamanlılık Modunu Sabit olarak değiştirin.

ConcurrencyMode of Course.VersionNo, Fixed olarak ayarlandığında, bir Kurs her güncellendiğinde, Update komutu Kursu EntityKey ve VersionNo özelliğini kullanarak arayacaktır.

Basit bir senaryoya bir göz atalım. İki kullanıcı aynı kursu aynı anda alır ve 1. kullanıcı bu kursun başlığını Matematik olarak değiştirir ve 2. kullanıcıdan önce değişiklikleri kaydeder. Daha sonra 2. kullanıcı, 1. kullanıcı değişikliklerini kaydetmeden önce alınan dersin başlığını değiştirdiğinde, durum kullanıcısı 2 eşzamanlılık istisnası alacak"User2: Optimistic Concurrency exception occured".

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;

namespace DatabaseFirstDemo {

   class Program {

      static void Main(string[] args) {

         Course c1 = null;
         Course c2 = null;

         //User 1 gets Course

         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c1 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }

         //User 2 also get the same Course

         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c2 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }

         //User 1 updates Course Title
         c1.Title = "Edited from user1";

         //User 2 updates Course Title
         c2.Title = "Edited from user2";

         //User 1 saves changes first

         using (var context = new UniContextEntities()) {

            try {
               context.Entry(c1).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User1: Optimistic Concurrency exception occurred");
            }
         }

         //User 2 saves changes after User 1.
         //User 2 will get concurrency exection
         //because CreateOrModifiedDate is different in the database

         using (var context = new UniContextEntities()) {

            try {
               context.Entry(c2).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User2: Optimistic Concurrency exception occurred");
            }
         }
      }
   }
}

Entity Framework'ün tüm sürümlerinde, her çalıştırdığınızda SaveChanges()Veritabanını eklemek, güncellemek veya silmek için, çerçeve bu işlemi bir işlemde sarmalayacaktır. SaveChanges'ı çağırdığınızda, içerik otomatik olarak bir işlemi başlatır ve kalıcılığın başarılı olup olmamasına bağlı olarak onu taahhüt eder veya geri alır.

  • Bunların hepsi sizin için şeffaftır ve bununla asla uğraşmanıza gerek kalmaz.

  • Bu işlem, yalnızca işlemi yürütmek için yeterince uzun sürer ve ardından tamamlanır.

  • Bu tür başka bir işlemi gerçekleştirdiğinizde, yeni bir işlem başlar.

Entity Framework 6 aşağıdakileri sağlar -

Database.BeginTransaction ()

  • Kullanıcılar için işlemleri başlatmak ve tamamlamak için mevcut bir DbContext içinde basit ve daha kolay bir yöntemdir.

  • Birkaç işlemin aynı işlem içinde birleştirilmesine izin verir ve bu nedenle, hepsi tamamlanır veya tümü tek bir işlem olarak geri alınır.

  • Ayrıca, kullanıcının işlem için yalıtım düzeyini daha kolay belirlemesine olanak tanır.

Database UseTransaction ()

  • DbContext'in Entity Framework dışında başlatılan bir işlemi kullanmasına izin verir.

Tek bir işlemde birden çok işlemin gerçekleştirildiği aşağıdaki örneğe bir göz atalım. Kod şu şekildedir:

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         using (var dbContextTransaction = context.Database.BeginTransaction()) {

            try {

               Student student = new Student() {
                  ID = 200, 
                  FirstMidName = "Ali", 
                  LastName = "Khan", 
                  EnrollmentDate = DateTime.Parse("2015-12-1")
               };

               context.Students.Add(student);

               context.Database.ExecuteSqlCommand(@"UPDATE Course SET Title = 
                  'Calculus'" + "WHERE CourseID = 1045");

               var query = context.Courses.Where(c ⇒ c.CourseID == 1045);

               foreach (var item in query) {
                  Console.WriteLine(item.CourseID.ToString()
                     + " " + item.Title + " " + item.Credits);
               }

               context.SaveChanges();
               var query1 = context.Students.Where(s ⇒ s.ID == 200);

               foreach (var item in query1) {
                  Console.WriteLine(item.ID.ToString() 
                     + " " + item.FirstMidName + " " + item.LastName);
               }

               dbContextTransaction.Commit();
            } catch (Exception) {
               dbContextTransaction.Rollback();
            }

         }
      }
   }
}
  • Bir işleme başlamak, temeldeki mağaza bağlantısının açık olmasını gerektirir.

  • Bu nedenle, Database.BeginTransaction () işlevini çağırmak, zaten açık değilse bağlantıyı açacaktır.

  • DbContextTransaction bağlantıyı açtıysa, Dispose () çağrıldığında kapatacaktır.

Görünüm, önceden tanımlanmış bir sorgu ile elde edilen verileri içeren bir nesnedir. Görünüm, sonuç kümesi bir sorgudan türetilen sanal bir nesne veya tablodur. Gerçek bir tabloya çok benzer çünkü sütunlar ve veri satırları içerir. Aşağıda görünümlerin bazı tipik kullanımları verilmiştir -

  • Temel tabloların verilerini filtrele
  • Verileri güvenlik amacıyla filtreleyin
  • Çeşitli sunuculara dağıtılan verileri merkezileştirin
  • Yeniden kullanılabilir bir veri kümesi oluşturun

Görünümler, tabloları kullanabildiğiniz gibi kullanılabilir. Görünümü bir varlık olarak kullanmak için, önce EDM'ye veritabanı görünümleri eklemeniz gerekir. Modelinize görünümler ekledikten sonra, Oluşturma, Güncelleme ve Silme işlemleri dışında normal varlıklarla aynı şekilde çalışabilirsiniz.

Veritabanından modele görünümlerin nasıl ekleneceğine bir göz atalım.

Step 1 - Yeni bir Konsol Uygulaması projesi oluşturun.

Step 2 - Çözüm gezgininde projeye sağ tıklayın ve Ekle → Yeni Öğe'yi seçin.

Step 3 - Orta bölmeden ADO.NET Varlık Veri Modeli'ni seçin ve Ad alanına ViewModel adını girin.

Step 4 - Varlık Veri Modeli Sihirbazı iletişim kutusunu başlatacak Ekle düğmesine tıklayın.

Step 5 - Veritabanından EF Designer'ı seçin ve İleri düğmesine tıklayın.

Step 6 - Mevcut veritabanını seçin ve İleri'ye tıklayın.

Step 7 - Entity Framework 6.x'i seçin ve İleri'ye tıklayın.

Step 8 - Veritabanınızdan tabloları ve görünümleri seçin ve Bitir'i tıklayın.

Tasarımcı penceresinde bir görünümün oluşturulduğunu görebilir ve bunu programda bir varlık olarak kullanabilirsiniz.

Çözüm gezgininde, MyView sınıfının da veritabanından oluşturulduğunu görebilirsiniz.

Tüm verilerin görünümden alındığı bir örnek alalım. Kod aşağıdadır -

class Program {

   static void Main(string[] args) {

      using (var db = new UniContextEntities()) {

         var query = from b in db.MyViews
            orderby b.FirstMidName select b;

         Console.WriteLine("All student in the database:");

         foreach (var item in query) {
            Console.WriteLine(item.FirstMidName + " " + item.LastName);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

All student in the database:
Ali Khan
Arturo   finand
Bill Gates
Carson Alexander
Gytis Barzdukas
Laura Norman
Meredith Alonso
Nino Olivetto
Peggy Justice
Yan Li
Press any key to exit...

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bir dizin, tablolara ve görünümlere dayanan bir disk üzerindeki veri yapısıdır. Dizinler, çoğu durumda verilerin daha hızlı ve verimli bir şekilde alınmasını sağlar. Ancak, bir tablonun veya görünümün dizinlerle aşırı yüklenmesi, eklemeler veya güncellemeler gibi diğer işlemlerin performansını istenmeyen bir şekilde etkileyebilir.

  • Dizin oluşturma, veritabanından verileri sorgulamak için gereken süreyi azaltarak Code First uygulamanızın performansını artırabileceğiniz varlık çerçevesindeki yeni özelliktir.

  • Veritabanınıza dizinler ekleyebilirsiniz. Index öznitelik ve varsayılanı geçersiz kılın Unique ve Clustered Senaryonuza en uygun dizini almak için ayarlar.

CourseID için Course sınıfına Index niteliğinin eklendiği aşağıdaki koda bir göz atalım.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   [Index]
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; }
   public byte[] VersionNo { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Yukarıda oluşturulan anahtar benzersiz değildir, kümelenmemiştir. Bu varsayılanları geçersiz kılmak için aşırı yükler var -

  • Bir dizini Kümelenmiş bir dizin yapmak için IsClustered = true belirtmeniz gerekir.

  • Benzer şekilde, IsUnique = true belirterek bir dizini benzersiz bir dizin yapabilirsiniz.

Bir dizinin kümelendiği ve benzersiz olduğu aşağıdaki C # koduna bir göz atalım.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   [Index(IsClustered = true, IsUnique = true)]
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; }
   public byte[] VersionNo { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Dizin niteliği, veritabanında benzersiz bir dizin oluşturmak için kullanılabilir. Bununla birlikte, bu, EF'in ilişkiler vb. İle uğraşırken sütunun benzersizliği hakkında akıl yürütebileceği anlamına gelmez. Bu özellik genellikle "benzersiz kısıtlamalar" desteği olarak adlandırılır.

Entity Framework, otomatik komut oluşturma yerine veya bununla birlikte Varlık Veri Modeli'nde saklı yordamları kullanmanıza olanak tanır.

  • Veritabanı tablolarında önceden tanımlanmış mantığı gerçekleştirmek için saklı yordamları kullanabilirsiniz ve birçok kuruluşun bu saklı yordamların kullanılmasını gerektiren yerinde ilkeleri vardır.

  • Ayrıca, EF'in varlıkları eklemek, güncellemek veya silmek için saklı yordamlarınızı kullanması gerektiğini de belirtebilir.

  • Dinamik olarak oluşturulmuş komutlar güvenli, verimli ve genellikle sizin yazdığınız kadar iyi veya daha iyi olsa da, depolanan yordamların zaten mevcut olduğu ve şirket uygulamalarınızın tabloların doğrudan kullanımını kısıtlayabildiği birçok durum vardır.

  • Alternatif olarak, mağazada nelerin yürütüldüğü üzerinde açık bir kontrole sahip olmak ve saklı yordamlar oluşturmayı tercih edebilirsiniz.

Aşağıdaki örnek, Dosya → Yeni → Proje'den yeni bir proje oluşturur.

Step 1 - Orta bölmeden Konsol Uygulamasını seçin ve ad alanına StoredProceduresDemo yazın.

Step 2 - Server explorer'da veritabanınıza sağ tıklayın.

Step 3 - Veritabanınıza yeni bir tablo eklemek için Yeni Sorgu öğesini seçin ve T-SQL düzenleyiciye aşağıdaki kodu girin.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = 
   OBJECT_ID(N'[dbo].[StudentGrade]') AND type in (N'U'))

BEGIN

   CREATE TABLE [dbo].[StudentGrade](

      [EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
      [CourseID] [int] NOT NULL,
      [StudentID] [int] NOT NULL,
      [Grade] [decimal](3, 2) NULL,

      CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED (
         [EnrollmentID] ASC
      )

      WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

   ) ON [PRIMARY]

END
GO

Step 4 - Düzenleyiciye sağ tıklayın ve Yürüt'ü seçin.

Step 5- Veritabanınıza sağ tıklayın ve yenile seçeneğine tıklayın. Veritabanınızda yeni eklenen tabloyu göreceksiniz.

Step 6 - Sunucu gezgininde, veritabanınıza tekrar sağ tıklayın.

Step 7 - Veritabanınıza Öğrenci notlarını döndürecek bir saklı yordam eklemek için Yeni Sorgu öğesini seçin ve aşağıdaki kodu T-SQL düzenleyicisine girin.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = 
   OBJECT_ID(N'[dbo].[GetStudentGrades]') AND type in (N'P', N'PC'))

BEGIN

   EXEC dbo.sp_executesql @statement = N'
   CREATE PROCEDURE [dbo].[GetStudentGrades]
   @StudentID int
   AS
   SELECT EnrollmentID, Grade, CourseID, StudentID FROM dbo.StudentGrade 
   WHERE StudentID = @StudentID
   '
END
GO

Step 8 - Düzenleyiciye sağ tıklayın ve Yürüt'ü seçin.

Step 9- Veritabanınıza sağ tıklayın ve yenile seçeneğine tıklayın. Veritabanınızda bir saklı yordamın oluşturulduğunu göreceksiniz.

Step 10 - Solution Explorer'da proje adına sağ tıklayın ve Add → New Item'ı seçin.

Step 11 - Ardından Şablonlar bölmesinde ADO.NET Varlık Veri Modeli'ni seçin.

Step 12 - SPModel'i ad olarak girin ve ardından Ekle'yi tıklayın.

Step 13 - Model İçeriğini Seçin iletişim kutusunda, veritabanından EF tasarımcısını seçin ve ardından İleri'ye tıklayın.

Step 14 - Veritabanınızı seçin ve İleri'ye tıklayın.

Step 15 - Veritabanı Nesnelerinizi Seçin iletişim kutusunda tablolara, görünümlere tıklayın.

Step 16 - Stored Procedures and Functions düğümünün altında bulunan GetStudentGradesForCourse işlevini seçin ve Bitir'i tıklayın.

Step 17 - Görünüm → Diğer Pencereler → Varlık Veri Modeli Tarayıcısı'nı seçin ve İşlev İçe Aktarmalar altında GetStudentGrades'e sağ tıklayın ve Düzenle'yi seçin.

Aşağıdaki diyaloğu üretecektir.

Step 18 - Varlıklar radyo düğmesine tıklayın ve bu saklı yordamın dönüş türü olarak birleşik giriş kutusundan StudentGrade öğesini seçin ve Tamam'a tıklayın.

GetStudentGrades saklı yordamında öğrenci kimliğini parametre olarak ileterek tüm notların alınacağı aşağıdaki C # koduna bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         int studentID = 22;
         var studentGrades = context.GetStudentGrades(studentID);

         foreach (var student in studentGrades) {
            Console.WriteLine("Course ID: {0}, Title: {1}, Grade: {2} ", 
               student.CourseID, student.Course.Title, student.Grade);
         }

         Console.ReadKey();

      }
   }
}

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız -

Course ID: 4022, Title: Microeconomics, Grade: 3.00
Course ID: 4041, Title: Macroeconomics, Grade: 3.50

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bu bölümde, bir bağlam tarafından izlenmeyen varlıklarda nasıl değişiklik yapılacağına bakalım. Bir bağlam tarafından izlenmeyen varlıklar, 'bağlantısı kesilmiş' varlıklar olarak bilinir.

  • Kullanıcı arabirimi ve veritabanı erişim katmanlarının aynı uygulama sürecinde çalıştığı çoğu tek katmanlı uygulama için, muhtemelen yalnızca bir bağlam tarafından izlenen varlıklar üzerinde işlemler gerçekleştiriyor olacaksınız.

  • Bağlantısı kesilen varlıklar üzerindeki işlemler, N-Katman uygulamalarında çok daha yaygındır.

  • N-Katmanlı uygulamalar, bir sunucudaki bazı verileri getirmeyi ve ağ üzerinden bir istemci makineye geri göndermeyi içerir.

  • İstemci uygulaması daha sonra bu verileri kalıcı olması için sunucuya geri göndermeden önce işler.

Bağlantısız varlık grafiği veya hatta tek bir bağlantısı kesilmiş varlık ile atılması gereken iki adım aşağıdadır.

  • Varlıkları yeni bağlam örneğiyle ekleyin ve bu varlıklar hakkında bağlamı bilinçlendirin.

  • Uygun EntityStates'i bu varlıklara manuel olarak ayarlayın.

Öğrenci varlığının iki Enrollment varlığıyla eklendiği aşağıdaki koda bir göz atalım.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram", 

         EnrollmentDate = DateTime.Parse("2015-10-10"), 
            Enrollments = new List<Enrollment> {

               new Enrollment{EnrollmentID = 2001,CourseID = 4022, StudentID = 1001 },
               new Enrollment{EnrollmentID = 2002,CourseID = 4025, StudentID = 1001 },
         }
      };

      using (var context = new UniContextEntities()) {

         context.Students.Add(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", 
               enrollment.EnrollmentID, context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   } 
}
  • Kod, Kayıtlar özelliğinde iki yeni Kayıt örneğine de başvuran yeni bir Öğrenci örneği oluşturur.

  • Daha sonra yeni Öğrenci, Add yöntemi kullanılarak bir bağlama eklenir.

  • Öğrenci eklendikten sonra, kod, Entity Framework'ün yeni Öğrenci hakkında sahip olduğu değişiklik izleme bilgilerine erişmek için DbContext.Entry yöntemini kullanır.

  • Bu değişiklik izleme bilgisinden, State özelliği, varlığın mevcut durumunu yazmak için kullanılır.

  • Bu süreç daha sonra yeni Öğrenci'den referans alınan yeni oluşturulan Kayıtların her biri için tekrarlanır. Uygulamayı çalıştırırsanız, aşağıdaki çıktıyı alırsınız -

New Student   (Wasim  Akram): Added
Enrollment ID: 2001 State: Added
Enrollment ID: 2002 State: Added
Press any key to exit...

Entity Framework'e yeni varlıklar hakkında bilgi vermek için DbSet.Add kullanılırken, DbSet.Attach Entity Framework'e var olan varlıklar hakkında bilgi vermek için kullanılır. Attach yöntemi, Değiştirilmemiş durumdaki bir varlığı işaretleyecektir.

DbContext ile bağlantısı kesilmiş bir varlığın eklendiği aşağıdaki C # koduna bir göz atalım.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram",
         EnrollmentDate = DateTime.Parse("2015-10-10"), 

         Enrollments = new List<Enrollment> {
            new Enrollment { EnrollmentID = 2001, CourseID = 4022, StudentID = 1001 },
            new Enrollment { EnrollmentID = 2002, CourseID = 4025, StudentID = 1001 },
         }
			
      };

      using (var context = new UniContextEntities()) {

         context.Students.Attach(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", enrollment.EnrollmentID, 
               context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   }
}

Yukarıdaki kod Attach () metodu ile çalıştırıldığında aşağıdaki çıktıyı alacaksınız.

New Student   (Wasim  Akram): Unchanged
Enrollment ID: 2001 State: Unchanged
Enrollment ID: 2002 State: Unchanged
Press any key to exit...

Bu bölümde, Entity Framework Designer kullanarak Tablo Değerli İşlevleri (TVF'ler) nasıl eşleyeceğimizi ve bir LINQ sorgusundan TVF'yi nasıl çağıracağımızı öğrenelim.

  • TVF'ler şu anda yalnızca Database First iş akışında desteklenmektedir.

  • İlk olarak Entity Framework sürüm 5'te tanıtıldı.

  • TVF'leri kullanmak için .NET Framework 4.5 veya üstünü hedeflemelisiniz.

  • Depolanmış prosedürlere çok benzer, ancak bir temel farkla, yani bir TVF'nin sonucu oluşturulabilir. Bu, bir TVF'den alınan sonuçların LINQ sorgusunda kullanılabileceği, ancak saklı yordamın sonuçlarının kullanılamayacağı anlamına gelir.

Dosya → Yeni → Proje'den yeni bir proje oluşturmanın aşağıdaki örneğine bir göz atalım.

Step 1 - Orta bölmeden Konsol Uygulamasını seçin ve ad alanına TableValuedFunctionDemo yazın.

Step 2 - Server explorer'da veritabanınıza sağ tıklayın.

Step 3 - Veritabanınıza yeni bir tablo eklemek için Yeni Sorgu öğesini seçin ve T-SQL düzenleyiciye aşağıdaki kodu girin.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id =
   OBJECT_ID(N'[dbo].[StudentGrade]') AND type in (N'U'))

BEGIN

   CREATE TABLE [dbo].[StudentGrade](

      [EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
      [CourseID] [int] NOT NULL,
      [StudentID] [int] NOT NULL,
      [Grade] [decimal](3, 2) NULL,

      CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED ([EnrollmentID] ASC)

      WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

   ) ON [PRIMARY]

END
GO

Step 4 - Düzenleyiciye sağ tıklayın ve Yürüt'ü seçin.

Step 5- Veritabanınıza sağ tıklayın ve yenile seçeneğine tıklayın. Veritabanınızda yeni eklenen tabloyu göreceksiniz.

Step 6- Şimdi ders için öğrenci notlarını döndürecek bir işlev oluşturun. T-SQL editörüne aşağıdaki kodu girin.

CREATE FUNCTION [dbo].[GetStudentGradesForCourse]

(@CourseID INT)

RETURNS TABLE

RETURN
   SELECT [EnrollmentID],
      [CourseID],
      [StudentID],
      [Grade]
   FROM   [dbo].[StudentGrade]
   WHERE  CourseID = @CourseID

Step 7 - Düzenleyiciye sağ tıklayın ve Yürüt'ü seçin.

Şimdi fonksiyonun oluşturulduğunu görebilirsiniz.

Step 8 - Solution Explorer'da proje adına sağ tıklayın ve Add → New Item'ı seçin.

Step 9 - Ardından Şablonlar bölmesinde ADO.NET Varlık Veri Modeli'ni seçin.

Step 10 - Ad olarak TVFModel girin ve ardından Ekle'yi tıklayın.

Step 11 - Model İçeriğini Seçin iletişim kutusunda, veritabanından EF tasarımcısını seçin ve ardından İleri'ye tıklayın.

Step 12 - Veritabanınızı seçin ve İleri'ye tıklayın.

Step 13 - Veritabanı Nesnelerinizi Seçin iletişim kutusunda tabloları, görünümleri seçin.

Step 14 - Stored Procedures and Functions düğümünün altında bulunan GetStudentGradesForCourse işlevini seçin ve Bitir'i tıklayın.

Step 15 - Görünüm → Diğer Pencereler → Varlık Veri Modeli Tarayıcısı'nı seçin ve İşlev İçe Aktarmalar altında GetStudentGradesForCourse'a sağ tıklayın ve Düzenle'yi seçin.

Aşağıdaki iletişim kutusunu göreceksiniz.

Step 16 - Varlıklar radyo düğmesine tıklayın ve bu İşlevin dönüş türü olarak birleşik giriş kutusundan Kayıt'ı seçin ve Tamam'a tıklayın.

Veritabanında Ders ID = 4022'ye kayıtlı olan tüm öğrencilerin notlarının alınacağı aşağıdaki C # koduna bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var CourseID = 4022;

         // Return all the best students in the Microeconomics class.
         var students = context.GetStudentGradesForCourse(CourseID);

         foreach (var result in students) {
            Console.WriteLine("Student ID:  {0}, Grade: {1}",
               result.StudentID, result.Grade);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız -

Student ID: 1, Grade: 2
Student ID: 4, Grade: 4
Student ID: 9, Grade: 3.5

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework'te, LINQ kullanarak varlık sınıflarınızla sorgulayabilirsiniz. DbCOntext kullanarak doğrudan veritabanı üzerinde ham SQL kullanarak sorguları da çalıştırabilirsiniz. Teknikler, Code First ve EF Designer ile oluşturulan modellere eşit olarak uygulanabilir.

Mevcut Varlık Üzerinde SQL Sorgusu

DbSet üzerindeki SqlQuery yöntemi, varlık örneklerini döndürecek ham bir SQL sorgusunun yazılmasına izin verir. Döndürülen nesneler, bir LINQ sorgusu tarafından döndürülselerdi olduğu gibi bağlam tarafından izlenecektir. Örneğin -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var students = context.Students.SqlQuery("SELECT * FROM dbo.Student").ToList();

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ",
               student.ID, name, student.EnrollmentDate.ToString());
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod tüm öğrencileri veritabanından alacaktır.

Varlık Olmayan Türler için SQL Sorgusu

İlkel türler de dahil olmak üzere her türden örnekleri döndüren bir SQL sorgusu, Veritabanı sınıfındaki SqlQuery yöntemi kullanılarak oluşturulabilir. Örneğin -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var studentNames = context.Database.SqlQuery
            <string>("SELECT FirstMidName FROM dbo.Student").ToList();

         foreach (var student in studentNames) {
            Console.WriteLine("Name: {0}", student);
         }

         Console.ReadKey();
      }
   }
}

Veritabanına SQL Komutları

ExecuteSqlCommnad yöntemi, Ekle, Güncelle veya Sil komutu gibi sorgu olmayan komutları veritabanına göndermede kullanılır. Öğrencinin adının ID = 1 olarak güncellendiği aşağıdaki koda bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         //Update command

         int noOfRowUpdated = context.Database.ExecuteSqlCommand("Update 
            student set FirstMidName = 'Ali' where ID = 1");

         context.SaveChanges();

         var student = context.Students.SqlQuery("SELECT * FROM
            dbo.Student where ID = 1").Single();

         string name = student.FirstMidName + " " + student.LastName;

         Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ", 
            student.ID, name, student.EnrollmentDate.ToString());

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod, tüm öğrencilerin adını veritabanından alacaktır.

Entity Framework'te bu özellik, bir enum türü olan bir etki alanı sınıfında bir özellik tanımlamanıza ve bunu tamsayı türündeki bir veritabanı sütununa eşlemenize olanak tanır. Entity Framework, verileri sorgulayıp kaydederken veritabanı değerini ilgili numaralandırmaya ve bu numaradan dönüştürür.

  • Numaralandırılmış türler, sabit sayıda yanıta sahip özelliklerle çalışırken her türlü avantaja sahiptir.

  • Bir uygulamanın güvenliği ve güvenilirliği, numaralandırmaları kullandığınızda artar.

  • Numaralandırma, kullanıcının hata yapmasını çok daha zor hale getirir ve enjeksiyon saldırıları gibi sorunlar mevcut değildir.

  • Entity Framework'te, bir numaralandırma aşağıdaki temel türlere sahip olabilir - In Entity Framework, an enumeration can have the following underlying types -

    • Byte
    • Int16
    • Int32
    • Int64
    • SByte
  • Numaralandırma öğelerinin varsayılan temel türü int'dir.

  • Varsayılan olarak, ilk numaralandırıcı 0 değerine sahiptir ve her ardışık numaralandırıcının değeri 1 artırılır.

Designer'da bir varlık oluşturacağımız ve ardından bazı özellikler ekleyeceğimiz aşağıdaki örneğe bir göz atalım.

Step 1 - Dosya → Yeni → Proje menü seçeneğinden yeni proje oluşturun.

Step 2 - Sol bölmede Konsol Uygulamasını seçin.

Step 3 - Proje adı olarak EFEnumDemo girin ve Tamam'a tıklayın.

Step 4 - Solution Explorer'da proje adına sağ tıklayın ve Add → New Item menü seçeneğini seçin.

Step 5 - Şablonlar bölmesinde ADO.NET Varlık Veri Modeli'ni seçin.

Step 6 - Dosya adı için EFEnumModel.edmx girin ve ardından Ekle'yi tıklayın.

Step 7 - Varlık Veri Modeli Sihirbazı sayfasında Boş EF tasarımcısı Modeli'ni seçin.

Step 8 - Bitir'i tıklayın

Step 9 - Ardından tasarımcı penceresine sağ tıklayın ve Ekle → Varlık öğesini seçin.

Aşağıdaki görüntüde gösterildiği gibi Yeni Varlık iletişim kutusu belirir.

Step 10 - Departmanı Varlık adı olarak ve DeptID'yi bir özellik adı olarak girin, Özellik türünü Int32 olarak bırakın ve Tamam'ı tıklayın.

Step 11 - Varlığa sağ tıklayın ve Yeni → Skaler Özellik Ekle'yi seçin.

Step 12 - Yeni özelliği DeptName olarak yeniden adlandırın.

Step 13 - Yeni özelliğin türünü Int32 olarak değiştirin (varsayılan olarak, yeni özellik String türündedir).

Step 14 - Türü değiştirmek için Özellikler penceresini açın ve Tür özelliğini Int32 olarak değiştirin.

Step 15 - Entity Framework Designer'da, Ad özelliğine sağ tıklayın, Numaralandırmaya Dönüştür'ü seçin.

Step 16 - Enum Türü Ekle iletişim kutusunda, Sıralama Türü Adı için Departman Adlarını girin, Temel Türü Int32 olarak değiştirin ve ardından aşağıdaki üyeleri türe ekleyin: Fizik, Kimya, Bilgisayar ve Ekonomi.

Step 17 - Tamam'ı tıklayın.

Model Tarayıcısı penceresine geçerseniz, türün Enum Türleri düğümüne de eklendiğini göreceksiniz.

Model İlk yaklaşım bölümünde belirtilen tüm adımları takip ederek modelden veri tabanı oluşturalım.

Step 1 - Varlık Tasarımcısı yüzeyine sağ tıklayın ve Modelden Veritabanı Oluştur'u seçin.

Veritabanı Oluştur Sihirbazının Veri Bağlantınızı Seçin İletişim Kutusu görüntülenir.

Step 2 - Yeni Bağlantı düğmesini tıklayın.

Step 3 - Veritabanı için sunucu adını ve EnumDemo'yu girin ve Tamam'ı tıklayın.

Step 4 - Yeni bir veritabanı oluşturmak isteyip istemediğinizi soran bir iletişim kutusu açılır, Evet'e tıklayın.

Step 5- İleri'ye tıklayın ve Veritabanı Oluştur Sihirbazı bir veritabanı oluşturmak için veri tanımlama dili (DDL) oluşturur. Şimdi Bitir'e tıklayın.

Step 6 - T-SQL Editör'e sağ tıklayın ve Yürüt'ü seçin.

Step 7 - Oluşturulan şemayı görüntülemek için SQL Server Nesne Gezgini'nde veritabanı adına sağ tıklayın ve Yenile'yi seçin.

Veritabanında Departments tablosunu göreceksiniz.

İçeriğe bazı yeni Departman nesnelerinin eklendiği ve kaydedildiği aşağıdaki örneğe bir göz atalım. Ve sonra Bilgisayar departmanını geri getirin.

class Program {

   static void Main(string[] args) {

      using (var context = new EFEnumModelContainer()) {

         context.Departments.Add(new Department { DeptName = DepartmentNames.Physics});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Computer});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Chemistry});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Economics});

         context.SaveChanges();

         var department = (
            from d in context.Departments
            where d.DeptName == DepartmentNames.Computer
            select d
         ).FirstOrDefault();

         Console.WriteLine(
            "Department ID: {0}, Department Name: {1}", 
               department.DeptID, department.DeptName
         );

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

Department ID: 2, Department Name: Computer

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Asynchronous programmingAna iş parçacığının kendi işlemlerine devam edebilmesi için arka planda işlemlerin yürütülmesini içerir. Bu şekilde, ana iş parçacığı, arka plan iş parçacığı eldeki görevi işlerken kullanıcı arabirimini duyarlı tutabilir.

  • Entity Framework 6.0, verilerin sorgulanması ve kaydedilmesi için zaman uyumsuz işlemleri destekler.

  • Eşzamansız işlemler uygulamanıza aşağıdaki şekillerde yardımcı olabilir:

    • Uygulamanızı kullanıcı etkileşimlerine daha duyarlı hale getirin
    • Uygulamanızın genel performansını iyileştirin
  • Eşzamansız işlemleri çeşitli şekillerde yürütebilirsiniz. Ancak async / await anahtar sözcükleri, işinizi basitleştiren .NET Framework 4.5'te tanıtılmıştır.

  • Takip etmeniz gereken tek şey, aşağıdaki kod parçasında gösterildiği gibi zaman uyumsuz / bekleme modelidir.

DatabaseOperations yönteminin yeni bir öğrenciyi veritabanına kaydettiği ve ardından tüm öğrencileri veritabanından aldığı ve sonunda konsolda bazı ek mesajların yazdırıldığı aşağıdaki örneğe (async / await kullanmadan) bir göz atalım.

class Program {

   static void Main(string[] args) {
      Console.WriteLine("Database Operations Started");
      DatabaseOperations();
		
      Console.WriteLine();
      Console.WriteLine("Database Operations Completed");
      Console.WriteLine();
      Console.WriteLine("Entity Framework Tutorials");
      Console.ReadKey();
   }

   public static void DatabaseOperations() {

      using (var context = new UniContextEntities()) {

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Akram", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())});

         Console.WriteLine("Calling SaveChanges.");
         context.SaveChanges();
         Console.WriteLine("SaveChanges completed.");

         // Query for all Students ordered by first name

         var students = (from s in context.Students
            orderby s.FirstMidName select s).ToList();

         // Write all students out to Console

         Console.WriteLine();
         Console.WriteLine("All Student:");

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine(" " + name);
         }
      }
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

Calling SaveChanges.
SaveChanges completed.
All Student:
Akram Khan
Ali Khan
Ali Alexander
Arturo Anand
Bill Gates
Gytis Barzdukas
Laura  Nornan
Meredith fllonso
Nino Olioetto
Peggy Justice
Yan Li

Entity Framework Tutorials

Yeni async'i kullanalım ve anahtar kelimeleri bekleyelim ve Program.cs'de aşağıdaki değişiklikleri yapalım.

  • EF zaman uyumsuz uzantı yöntemlerini verecek System.Data.Entity ad alanını ekleyin.

  • Görev türünü kullanmamıza izin verecek System.Threading.Tasks ad alanını ekleyin.

  • Güncelleme DatabaseOperations olarak işaretlenmek async ve dön Task.

  • SaveChanges'ın Async sürümünü çağırın ve tamamlanmasını bekleyin.

  • ToList'in Async sürümünü çağırın ve sonucu bekleyin.

class Program {

   static void Main(string[] args) {
      var task = DatabaseOperations();
      Console.WriteLine();
      Console.WriteLine("Entity Framework Tutorials");
      task.Wait();
      Console.ReadKey();
   }

   public static async Task DatabaseOperations() {

      using (var context = new UniContextEntities()) {

         // Create a new blog and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())});

         Console.WriteLine("Calling SaveChanges.");
         await context.SaveChangesAsync();
         Console.WriteLine("SaveChanges completed.");

         // Query for all Students ordered by first name

         var students = await (from s in context.Students 
            orderby s.FirstMidName select s).ToListAsync();

         // Write all students out to Console

         Console.WriteLine();
         Console.WriteLine("All Student:");

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName; 
            Console.WriteLine(" " + name);
         }
      }
   }
}

Yürütme sırasında aşağıdaki çıktıyı üretecektir.

Calling SaveChanges.
Entity Framework Tutorials
SaveChanges completed.
All Student:
Akram Khan
Ali Khan
Ali Alexander
Arturo Anand
Bill Gates
Gytis Barzdukas
Laura  Nornan
Meredith fllonso
Nino Olioetto
Peggy Justice
Salman Khan
Yan Li

Artık kod eşzamansız olduğuna göre, programınızın farklı bir yürütme akışını gözlemleyebilirsiniz.

  • SaveChanges, yeni Student'ı veritabanına göndermeye başlar ve ardından DatabaseOperations yöntemi geri döner (yürütmeyi bitirmemiş olsa bile) ve Main yöntemindeki program akışı devam eder.

  • Mesaj daha sonra konsola yazılır.

  • Yönetilen iş parçacığı, veritabanı işlemi tamamlanıncaya kadar Bekle çağrısında engellenir. Tamamlandığında, Veritabanı İşlemlerimizin geri kalanı yürütülecektir.

  • SaveChanges tamamlandı.

  • Veritabanından tüm öğrenci alınır ve Konsola yazılır.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework artık, varlıkları altyapıdan ayırarak, uygulamanızın her parçasını Entity Framework'ün farkında olmaya zorlamadan Entity Framework'ten yararlanmanıza olanak tanır. Nasıl kalıcı olduklarına (verilerin nerede depolandığına ve verilerin nesneleriniz arasında nasıl gidip geldiğine) bakılmaksızın iş kurallarına odaklanabilen sınıflar oluşturabilirsiniz.

Kalıcı Cahil Varlıklar Oluşturma

Önceki paragraf, tükettiği verilerin kaynağı hakkında hiçbir yakın bilgiye sahip olmayan bir yöntemi açıkladı. Bu, kalıcılık cehaletinin özünü vurgular; bu, sınıflarınızın ve etraflarındaki uygulama katmanlarımızın çoğunun verilerin nasıl depolandığını umursamadığı zamandır.

  • Entity Framework .NET 3.5 sürümünde, önceden var olan sınıfları kullanmak istiyorsanız, onları EntityObject'ten türetmeye zorlayarak değiştirmeniz gerekirdi.

  • .NET 4'te bu artık gerekli değildir. Entity Framework işlemlerine katılmaları için varlıklarınızı değiştirmeniz gerekmez.

  • Bu, gevşek bağlantı ve endişelerin ayrılmasını benimseyen uygulamalar geliştirmemize olanak tanır.

  • Bu kodlama modelleriyle, sınıflarınız yalnızca kendi işleriyle ilgilenir ve UI dahil uygulamanızın birçok katmanının Entity Framework API'leri gibi harici mantığa bağımlılığı yoktur, ancak bu harici API'ler bizim varlıklar.

Entity Framework ile bir varlığı sürdürmenin 2 yolu vardır (bağlı ve bağlantısı kesilmiş). Her iki yolun da kendi önemi vardır. Bağlı bir senaryo durumunda, değişiklikler bağlam tarafından izlenir, ancak bağlantısız bir senaryo durumunda varlığın durumu hakkında bağlamı bilgilendirmemiz gerekir.

Bağlı Senaryolar

Bağlı senaryo, bir varlığın veritabanından alınması ve aynı bağlamda değiştirilmesidir. Bağlantılı bir senaryo için, bir Windows hizmetimiz olduğunu ve bu varlıkla bazı iş operasyonları yaptığımızı varsayalım, böylece içeriği açacağız, tüm varlıklar arasında döngü oluşturacağız, iş operasyonlarımızı yapacağız ve sonra değişiklikleri aynı bağlamda kaydedeceğiz. başlangıçta açıldı.

Öğrencilerin veritabanından alındığı ve öğrencilerin adını güncellediği ve ardından değişiklikleri veritabanına kaydettiği aşağıdaki örneğe bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new MyContext()) {

         var studentList = context.Students.ToList();

         foreach (var stdnt in studentList) {
            stdnt.FirstMidName = "Edited " + stdnt.FirstMidName;
         }

         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız ve aşağıdaki çıktıda gösterildiği gibi ilk adın önüne Düzenlenmiş sözcüğün eklendiğini göreceksiniz.

Retrieve all Students from the database: 
ID: 1, Name: Edited Edited Alain Bomer 
ID: 2, Name: Edited Edited Mark Upston

Bağlantısız Senaryolar

Bağlantısız senaryo, bir varlığın veritabanından alınması ve farklı bağlamda değiştirilmesidir. Bir Sunum Katmanında bazı verileri görüntülemek istediğimizi ve bazı n katmanlı uygulamalar kullandığımızı varsayalım, bu nedenle bağlamı açmak, verileri almak ve nihayet bağlamı kapatmak daha iyi olacaktır. Burada verileri getirdiğimiz ve bağlamı kapattığımız için, getirmiş olduğumuz varlıklar artık izlenmiyor ve bu bağlantısız senaryo.

Add yöntemini kullanarak yeni bağlantısı kesilmiş Student varlığının bir bağlama eklendiği aşağıdaki koda bir göz atalım.

class Program {

   static void Main(string[] args) {

      var student = new Student {
         ID = 1001, 
         FirstMidName = "Wasim", 
         LastName = "Akram", 
         EnrollmentDate = DateTime.Parse( DateTime.Today.ToString())
      };

      using (var context = new MyContext()) {

         context.Students.Add(student);
         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students 
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız.

Retrieve all Students from the database:
ID: 1, Name: Edited Edited Edited Alain Bomer
ID: 2, Name: Edited Edited Edited Mark Upston
ID: 3, Name: Wasim Akram

LINQ to Entities

LINQ to Entities'i anlamak için en önemli kavramlardan biri, bildirimsel bir dil olmasıdır. Odak noktası, bilgiyi nasıl elde edeceğinizden ziyade hangi bilgilere ihtiyacınız olduğunu belirlemektir.

  • Bu, verilerle çalışmaya daha fazla, veritabanına erişim gibi görevleri gerçekleştirmek için gereken temel kodu bulmaya daha az zaman harcayabileceğiniz anlamına gelir.

  • Bildirimsel dillerin aslında geliştiriciden herhangi bir kontrolü kaldırmadığını anlamak önemlidir, ancak geliştiricinin dikkatini önemli olana odaklamasına yardımcı olur.

LINQ to Entities Essential Keywords

Bir LINQ sorgusu oluşturmak için kullanılan temel anahtar kelimeleri bilmek önemlidir. Hatırlanması gereken yalnızca birkaç anahtar kelime vardır, ancak belirli sonuçları elde etmek için bunları çeşitli şekillerde birleştirebilirsiniz. Aşağıdaki liste bu temel anahtar kelimeleri içerir ve her birinin basit bir açıklamasını sağlar.

Sr. No. Anahtar Kelime ve Açıklama
1

Ascending

Bir aralığın en küçük (veya en düşük) öğesinden bir aralığın en yüksek öğesine kadar bir sıralama işleminin gerçekleştiğini belirtir. Bu normalde varsayılan ayardır. Örneğin, alfabetik bir sıralama gerçekleştirilirken, sıralama A ile Z arasında olacaktır.

2

By

Bir gruplamayı uygulamak için kullanılan alanı veya ifadeyi belirtir. Alan veya ifade, gruplama görevini gerçekleştirmek için kullanılan bir anahtarı tanımlar.

3

Descending

Bir aralığın en büyük (veya en yüksek) öğesinden aralığın en düşük öğesine kadar bir sıralama işleminin gerçekleştiğini belirtir. Örneğin, alfabetik bir sıralama gerçekleştirilirken, sıralama Z ile A arasında olacaktır.

4

Equals

Birleştirme ifadesinin sol ve sağ cümleleri arasında, birincil bağlamsal veri kaynağını ikincil bağlamsal veri kaynağına birleştirmek için kullanılır. Equals anahtar kelimesinin solundaki alan veya ifade birincil veri kaynağını belirtirken, equals anahtar kelimesinin sağındaki alan veya ifade ikincil veri kaynağını belirtir.

5

From

Gerekli bilgileri elde etmek için kullanılan veri kaynağını belirtir ve bir aralık değişkenini tanımlar. Bu değişken, bir döngüde yineleme için kullanılan bir değişkenle aynı amaca sahiptir.

6

Group

Çıktıyı, belirlediğiniz anahtar değerini kullanarak gruplar halinde düzenler. Birden çok düzeyde çıktı organizasyonu oluşturmak için birden çok grup cümlesi kullanın. Grup cümlelerinin sırası, gruplama sırasında belirli bir anahtar değerinin göründüğü derinliği belirler. Belirli bir bağlam oluşturmak için bu anahtar kelimeyi by ile birleştirirsiniz.

7

In

Çeşitli şekillerde kullanılır. Bu durumda anahtar sözcük, bir sorgu için kullanılan bağlamsal veritabanı kaynağını belirler. Bir birleştirme ile çalışırken, birleştirme için kullanılan her bağlamsal veritabanı kaynağı için in anahtar sözcüğü kullanılır.

8

Into

Join, group ve select gibi LINQ sorgu yan tümceleri için başvuru olarak kullanabileceğiniz bir tanımlayıcı belirtir.

9

Join

Ana / ayrıntı kurulumunda olduğu gibi iki ilgili veri kaynağından tek bir veri kaynağı oluşturur. Bir birleşim, iç birleşim varsayılan olarak bir iç, grup veya sol dış birleşimi belirtebilir. Msdn.microsoft.com adresinde birleştirmeler hakkında daha fazla bilgi edinebilirsiniz.

10

Let

Alt ifade sonuçlarını bir sorgu ifadesinde depolamak için kullanabileceğiniz bir aralık değişkenini tanımlar. Tipik olarak, aralık değişkeni, ek bir numaralandırılmış çıktı sağlamak veya bir sorgunun verimliliğini artırmak için kullanılır (böylece, bir dizenin küçük harfli değerini bulmak gibi belirli bir görevin birden fazla kez yapılması gerekmez).

11

On

Bir birleştirmeyi uygulamak için kullanılan alanı veya ifadeyi belirtir. Alan veya ifade, her iki bağlamsal veri kaynağı için ortak olan bir öğeyi tanımlar.

12

Orderby

Sorgu için bir sıralama düzeni oluşturur. Sıralamanın sırasını kontrol etmek için artan veya azalan anahtar kelimeyi ekleyebilirsiniz. Birden çok sıralama düzeyi oluşturmak için birden çok orderby cümlesi kullanın. Orderby yan tümcelerinin sırası, sıralama ifadelerinin işlenme sırasını belirler, bu nedenle farklı bir sıra kullanmak farklı çıktılarla sonuçlanır.

13

Where

LINQ'nun veri kaynağından alması gerekenleri tanımlar. Neyin alınacağının ayrıntılarını tanımlamak için bir veya daha fazla Boole ifadesi kullanırsınız. Boole ifadeleri, && (VE) ve || kullanılarak birbirinden ayrılır. (VEYA) operatörleri.

14

Select

Hangi bilgilerin döndürüleceğini belirterek LINQ sorgusunun çıktısını belirler. Bu ifade, yineleme işlemi sırasında LINQ'nun döndürdüğü öğelerin veri türünü tanımlar.

Projeksiyon

Projeksiyon sorguları, yalnızca veritabanınızdan belirli alanları alarak uygulamanızın verimliliğini artırır.

  • Verilere sahip olduğunuzda, verileri çıktıdan önce şekillendirmek için gerektiği gibi yansıtmak veya filtrelemek isteyebilirsiniz.

  • Herhangi bir LINQ to Entities ifadesinin ana görevi, verileri elde etmek ve çıktı olarak sağlamaktır.

Bu bölümün "LINQ to Entities sorgularının geliştirilmesi" bölümü, bu temel görevi gerçekleştirmek için gereken teknikleri gösterir.

Öğrencilerin listesinin alınacağı aşağıdaki koda bir göz atalım.

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students select s;

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }
}

Tek Nesne

Tek bir öğrenci nesnesini almak için, bir dizinin ilk öğesini döndüren First () veya FirstOrDefault numaralandırılabilir yöntemleri kullanabilirsiniz. First ve FirstOrDefault arasındaki fark, sağlanan ölçütler için sonuç verisi yoksa First () 'ün bir istisna atması, sonuç verisi yoksa FirstOrDefault ()' nun varsayılan değeri null döndürmesidir. Aşağıdaki kod parçacığında, listeden ilk adı Ali olan öğrenci alınacaktır.

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).FirstOrDefault<Student>();

   string name = student.FirstMidName + " " + student.LastName;
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}

Bir sıranın tek, belirli bir öğesini döndüren tek bir öğrenci nesnesi almak için Single () veya SingleOrDefault'u da kullanabilirsiniz. Aşağıdaki örnekte, kimliği 2 olan tek bir öğrenci alınır.

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.ID 
      == 2 select s).SingleOrDefault<Student>();
   string name = student.FirstMidName + " " + student.LastName;
	
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   Console.ReadKey();
}

Nesnelerin Listesi

İlk adı Ali olan öğrencilerin listesini almak istiyorsanız ToList () numaralandırılabilir yöntemi kullanabilirsiniz.

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Sipariş

Verileri / listeyi belirli bir sırada almak için anahtar kelimeye göre sıralamayı kullanabilirsiniz. Aşağıdaki kodda, öğrencinin snippet listesi artan sırada alınacaktır.

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students orderby
      s.FirstMidName ascending select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Standard Vs Projection Entity Framework Sorgusu

Diyelim ki ID, FirstMidName, LastName ve EnrollmentDate içeren bir Student modeliniz var. Bir Öğrenci listesi döndürmek istiyorsanız, standart bir sorgu tüm alanları döndürür. Ancak, yalnızca ID, FirstMidName ve LastName alanlarını içeren öğrencilerin bir listesini almak istiyorsanız. Projeksiyon sorgusu kullanmanız gereken yer burasıdır. Aşağıda, projeksiyon sorgusunun basit bir örneği verilmiştir.

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students
      orderby s.FirstMidName ascending
      where s.FirstMidName == "Ali"

   select new {s.ID, s.FirstMidName, s.LastName};

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Yukarıdaki projeksiyon sorgusu KayıtTarihi alanını hariç tutar. Bu, uygulamanızı çok daha hızlı hale getirecektir.

Entity Framework 6.0'da, olarak bilinen yeni bir özellik tanıtıldı Logging SQL. Entity Framework ile çalışırken, CRUD (Oluşturma, Okuma, Güncelleme ve Silme) işlemleri yapmak için veritabanına komutlar veya eşdeğer bir SQL sorgusu gönderir.

  • Entity Framework'ün bu özelliği, Entity Framework tarafından dahili olarak oluşturulan eşdeğer bir SQL sorgusunu yakalamak ve bunu çıktı olarak sağlamaktır.

  • Entity Framework 6'dan önce, veritabanı sorgularını ve komutlarını izleme ihtiyacı duyulduğunda geliştiricinin bazı üçüncü taraf izleme yardımcı programını veya veritabanı izleme aracını kullanmaktan başka seçeneği yoktu.

  • Entity Framework 6'da bu yeni özellik, Entity Framework tarafından gerçekleştirilen tüm işlemleri günlüğe kaydederek basit bir yol sağlar.

  • Entity Framework tarafından gerçekleştirilen tüm etkinlikler DbContext.Database.Log kullanılarak günlüğe kaydedilir.

Veritabanına yeni bir öğrencinin eklendiği aşağıdaki koda bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Database.Log = Console.Write;

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         context.SaveChanges();
         Console.ReadKey();
      }
   }
}

Yukarıdaki kod çalıştırıldığında, aslında yukarıdaki kodda EF tarafından gerçekleştirilen tüm etkinliklerin günlüğü olan aşağıdaki çıktıyı alacaksınız.

Opened connection at 10/28/2015 6:27:35 PM +05:00
Started transaction at 10/28/2015 6:27:35 PM +05:00
INSERT [dbo].[Student]([LastName], [FirstMidName], [EnrollmentDate])
VALUES (@0, @1, @2)
SELECT [ID]
FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()
-- @0: 'Khan' (Type = String, Size = -1)
-- @1: 'Salman' (Type = String, Size = -1)
-- @2: '10/28/2015 12:00:00 AM' (Type = DateTime)
-- Executing at 10/28/2015 6:27:35 PM +05:00
-- Completed in 5 ms with result: SqlDataReader
Committed transaction at 10/28/2015 6:27:35 PM +05:00
Closed connection at 10/28/2015 6:27:35 PM +05:00

Log özelliği ayarlandığında, aşağıdaki etkinlikler günlüğe kaydedilir -

  • SaveChanges'ın bir parçası olarak oluşturulan eklemeler, güncellemeler ve silmeler dahil olmak üzere Sorgular gibi tüm farklı komut türleri için SQL

  • Parameters

  • Komutun eşzamansız olarak yürütülüp yürütülmediği

  • Komutun ne zaman yürütülmeye başladığını gösteren bir zaman damgası

  • Komut başarıyla tamamlandı veya başarısız oldu

  • Sonuç değerinin bazı göstergeleri

  • Komutu çalıştırmak için geçen yaklaşık süre

Başka Bir Yerde Oturum Açma

Zaten bir günlükleme çerçeveniz varsa ve bu bir günlük kaydı yöntemini tanımlıyorsa, başka bir yere de kaydedebilirsiniz.

Başka bir MyLogger sınıfına sahip olduğumuz aşağıdaki örneğe bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Database.Log = s ⇒ MyLogger.Log("EFLoggingDemo", s);

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         context.SaveChanges();
         Console.ReadKey();
      }
   }
}

public class MyLogger {

   public static void Log(string application, string message) {
      Console.WriteLine("Application: {0}, EF Message: {1} ",application, message);
   }
}

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework 6.0'da, olarak bilinen başka bir yeni özellik vardır. Interceptorveya Engelleme. Müdahale kodu,interception interfaces. Örneğin, IDbCommandInterceptor arabirimi, EF, ExecuteNonQuery, ExecuteScalar, ExecuteReader ve ilgili yöntemlere çağrı yapmadan önce çağrılan yöntemleri tanımlar.

  • Entity Framework, engellemeyi kullanarak gerçekten parlayabilir. Bu yaklaşımı kullanarak, kodunuzu temizlemek zorunda kalmadan çok daha fazla bilgiyi geçici olarak yakalayabilirsiniz.

  • Bunu uygulamak için, kendi özel durdurucunuzu oluşturmanız ve buna göre kaydetmeniz gerekir.

  • IDbCommandInterceptor arabirimini uygulayan bir sınıf oluşturulduktan sonra, DbInterception sınıfı kullanılarak Entity Framework ile kaydedilebilir.

  • IDbCommandInterceptor arabiriminin altı yöntemi vardır ve tüm bu yöntemleri uygulamanız gerekir. Bu yöntemlerin temel uygulaması aşağıdadır.

IDbCommandInterceptor arayüzünün uygulandığı aşağıdaki koda bir göz atalım.

public class MyCommandInterceptor : IDbCommandInterceptor {

   public static void Log(string comm, string message) {
      Console.WriteLine("Intercepted: {0}, Command Text: {1} ", comm, message);
   }

   public void NonQueryExecuted(DbCommand command, 
      DbCommandInterceptionContext<int> interceptionContext) {
         Log("NonQueryExecuted: ", command.CommandText);
   }

   public void NonQueryExecuting(DbCommand command, 
      DbCommandInterceptionContext<int> interceptionContext) {
         Log("NonQueryExecuting: ", command.CommandText);
   }

   public void ReaderExecuted(DbCommand command, 
      DbCommandInterceptionContext<DbDataReader> interceptionContext) {
         Log("ReaderExecuted: ", command.CommandText);
   }

   public void ReaderExecuting(DbCommand command, 
      DbCommandInterceptionContext<DbDataReader> interceptionContext) {
         Log("ReaderExecuting: ", command.CommandText);
   }

   public void ScalarExecuted(DbCommand command, 
      DbCommandInterceptionContext<object> interceptionContext) {
         Log("ScalarExecuted: ", command.CommandText);
   }

   public void ScalarExecuting(DbCommand command, 
      DbCommandInterceptionContext<object> interceptionContext) {
         Log("ScalarExecuting: ", command.CommandText);
   }

}

Durdurucuları Kaydetme

Bir veya daha fazla durdurma arabirimini uygulayan bir sınıf oluşturulduktan sonra, aşağıdaki kodda gösterildiği gibi DbInterception sınıfı kullanılarak EF ile kaydedilebilir.

DbInterception.Add(new MyCommandInterceptor());

Interceptors, aşağıdaki kodda gösterildiği gibi DbConfiguration kod tabanlı yapılandırma kullanılarak uygulama etki alanı düzeyinde de kaydedilebilir.

public class MyDBConfiguration : DbConfiguration {

   public MyDBConfiguration() {
      DbInterception.Add(new MyCommandInterceptor());
   }
}

Interceptor yapılandırma dosyasını şu kodu kullanarak da yapılandırabilirsiniz -

<entityFramework>
   <interceptors>
      <interceptor type = "EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
   </interceptors>
</entityFramework>

Uzamsal tür desteği Entity Framework 5'te sunulmuştur. Sorguların uzamsal verileri analiz etmesine izin vermek için bir dizi işleç de dahil edilmiştir. Örneğin, bir sorgu iki coğrafi konum arasındaki mesafeye göre filtre uygulayabilir.

  • Entity Framework, yeni uzamsal veri türlerinin sınıflarınızda özellikler olarak gösterilmesine ve bunları veritabanınızdaki uzamsal sütunlarla eşleştirmesine izin verir.

  • Ayrıca, veritabanında gerçekleştirilen uzamsal hesaplamaları temel alarak filtrelemek, sıralamak ve gruplandırmak için uzamsal operatörleri kullanan LINQ sorguları yazabileceksiniz.

İki ana uzamsal veri türü vardır -

  • Coğrafya veri türü, elipsoidal verileri, örneğin GPS enlem ve boylam koordinatlarını depolar.

  • Geometri veri türü Öklid (düz) koordinat sistemini temsil eder.

Aşağıdaki Cricket Ground örneğine bir göz atalım.

Step 1 - Dosya → Yeni → Proje menü seçeneğinden yeni proje oluşturun.

Step 2 - Sol bölmede Konsol Uygulamasını seçin.

Step 3 - Proje adına sağ tıklayın ve NuGet Paketlerini Yönet… öğesini seçin.

Step 4 - Entity Framework'ü yükleyin.

Step 5 - System.Data.Entity derlemesine başvuru ekleyin ve ayrıca uzamsal veri türleri için System.Data.Spatial using deyimini ekleyin.

Step 6 - Aşağıdaki sınıfı Program.cs dosyasına ekleyin.

public class CricketGround {
   public int ID { get; set; }
   public string Name { get; set; }
   public DbGeography Location { get; set; }
}

Step 7 - Varlıkları tanımlamaya ek olarak, DbContext'ten türetilen ve DbSet <TEntity> özelliklerini ortaya çıkaran bir sınıf tanımlamanız gerekir.

Program.cs dosyasında bağlam tanımını ekleyin.

public partial class CricketGroundContext : DbContext {
   public DbSet<CricketGround> CricketGrounds { get; set; }
}

Step 8 - Bağlama iki yeni CricketGround nesnesi ekleyecek olan Main işlevine aşağıdaki kodu ekleyin.

class Program {

   static void Main(string[] args) {

      using (var context = new CricketGroundContext()) {

         context.CricketGrounds.Add(new CricketGround() {
            Name = "Shalimar Cricket Ground", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
         });

         context.CricketGrounds.Add(new CricketGround() {
            Name = "Marghazar Stadium", Location = DbGeography
               .FromText("POINT(-122.335197 47.646711)"), 
         });

         context.SaveChanges();

         var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)");

         var cricketGround = (from cg in context.CricketGrounds
            orderby cg.Location.Distance(myLocation) select cg).FirstOrDefault();

         Console.WriteLine("The closest Cricket Ground to you is: {0}.", cricketGround.Name);
      }
   }
}

Uzamsal özellikler, DbGeography.FromText yöntemi kullanılarak başlatılır. WellKnownText olarak temsil edilen coğrafya noktası yönteme iletilir ve ardından verileri kaydeder. Bundan sonra CricketGround nesnesi, konumu belirtilen konuma en yakın olan yerden alınacaktır.

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

The closest Cricket Ground to you is: Marghazar Stadium

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Kalıtım, geliştiricilerin nasıl düşündüğünü daha iyi yansıtan karmaşık modeller oluşturmayı mümkün kılar ve aynı zamanda bu modellerle etkileşim için gerekli işi azaltır. Varlıklarla kullanılan kalıtım, sınıflarda kullanılan kalıtımla aynı amaca hizmet eder, bu nedenle geliştiriciler bu özelliğin nasıl çalıştığına dair temel bilgileri zaten bilirler.

Aşağıdaki örneğe bir göz atalım ve yeni bir konsol uygulama projesi oluşturalım.

Step 1 - Proje adına sağ tıklayarak ADO.NET Varlık Veri Modeli ekleyin ve Ekle → Yeni Öğe… öğesini seçin.

Step 2 - Bir varlık ekleyin ve Model First yaklaşımı bölümünde belirtilen tüm adımları izleyerek bunu Kişi olarak adlandırın.

Step 3 - Aşağıdaki resimde gösterildiği gibi bazı skaler özellikler ekleyin.

Step 4 - İki varlık daha ekleyeceğiz Student ve Teacher, özellikleri Kişi Tablosundan devralır.

Step 5 - Şimdi Öğrenci varlığını ekleyin ve aşağıdaki görüntüde gösterildiği gibi Temel türü birleşik giriş kutusundan Kişi'yi seçin.

Step 6 - Benzer şekilde Öğretmen varlığını ekleyin.

Step 7 - Şimdi öğrenci varlığına EnrollmentDate skaler özelliğini ve Öğretmen varlığına HireDate özelliğini ekleyin.

Step 8 - Devam edelim ve veritabanını oluşturalım.

Step 9 - Tasarım yüzeyine sağ tıklayın ve Modelden Veritabanı Oluştur'u seçin ...

Step 10- Yeni Veritabanı oluşturmak için Yeni Bağlantı'ya tıklayın… Aşağıdaki iletişim kutusu açılacaktır. Tamam'ı tıklayın.

Step 11- Bitir'i tıklayın. Bu, projeye * .edmx.sql dosyasını ekleyecektir. .Sql dosyasını açarak DDL betiklerini Visual Studio'da çalıştırabilirsiniz. Şimdi sağ tıklayın ve Yürüt'ü seçin.

Step 12 - Sunucu gezginine gidin, veritabanının belirtilen üç tabloyla oluşturulduğunu göreceksiniz.

Step 13 - Aşağıdaki alan sınıflarının da otomatik olarak oluşturulduğunu görebilirsiniz.

public partial class Person {
   public int ID { get; set; }
   public string FirstMidName { get; set; }
   public string LastName { get; set; }
}

public partial class Student : Person {
   public System.DateTime EnrollmentDate { get; set; }
}

public partial class Teacher : Person {
   public System.DateTime HireDate { get; set; }
}

Bağlam sınıfı aşağıdadır.

public partial class InheritanceModelContainer : DbContext {

   public InheritanceModelContainer() : 
      base("name = InheritanceModelContainer") {}

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      throw new UnintentionalCodeFirstException();
   }

   public virtual DbSet<Person> People { get; set; }
}

Veritabanına bazı Öğrenci ve Öğretmenler ekleyip ardından veritabanından alalım.

class Program {

   static void Main(string[] args) {

      using (var context = new InheritanceModelContainer()) {

         var student = new Student {
            FirstMidName = "Meredith", 
            LastName = "Alonso", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(student);

         var student1 = new Student {
            FirstMidName = "Arturo", 
            LastName = "Anand", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(student1);

         var techaer = new Teacher {
            FirstMidName = "Peggy", 
            LastName = "Justice", 
            HireDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(techaer);

         var techaer1 = new Teacher {
            FirstMidName = "Yan", 
            LastName = "Li", 
            HireDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(techaer1);
         context.SaveChanges();
      }
   }
}

Veritabanına öğrenciler ve öğretmenler eklenir. NT Öğrencileri ve öğretmeni geri almak,OfType Belirtilen bölümle ilgili Öğrenci ve Öğretmeni döndürecek yöntemin kullanılması gerekir.

Console.WriteLine("All students in database"); 
Console.WriteLine("");

foreach (var student in context.People.OfType<Student>()) {
   string name = student.FirstMidName + " " + student.LastName;
   Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ", 
      student.ID, name, student.EnrollmentDate.ToString());
}

Console.WriteLine("");
Console.WriteLine("************************************************************ *****");
Console.WriteLine("");
Console.WriteLine("All teachers in database");
Console.WriteLine("");

foreach (var teacher in context.People.OfType<Teacher>()) {
   string name = teacher.FirstMidName + " " + teacher.LastName;
   Console.WriteLine("ID: {0}, Name: {1}, \tHireDate {2} ", 
      teacher.ID, name, teacher.HireDate.ToString()); 
}

Console.WriteLine("");
Console.WriteLine("************************************************************ *****");
Console.ReadKey();

İlk sorguda, OfType <Student> () kullandığınızda HireDate'e erişemezsiniz çünkü HireDate özelliği Teacher Entity'nin bir parçasıdır ve benzer şekilde EnrollmentDate özelliği OfType <Teacher> () kullandığınızda erişilemez.

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız -

All students in database
ID: 1, Name: Meredith Alonso,   Enrollment Date 10/30/2015 12:00:00 AM
ID: 2, Name: Arturo Anand,      Enrollment Date 10/30/2015 12:00:00 AM
*****************************************************************  
All teachers in database
ID: 3, Name: Peggy Justice,     HireDate 10/30/2015 12:00:00 AM
ID: 4, Name: Yan Li,    HireDate 10/30/2015 12:00:00 AM
*****************************************************************

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework 5 ve Entity Framework'ün önceki sürümlerinde kod, .NET Framework'ün bir parçası olarak gönderilen çekirdek kitaplıklar (özellikle System.Data.Entity.dll) arasında bölündü ve ek kitaplıklar (özellikle EntityFramework.dll) dağıtıldı ve Aşağıdaki diyagramda gösterildiği gibi NuGet kullanılarak gönderilir.

Entity Framework 6'da, daha önce .NET çerçevesinin parçası olan temel API'ler de NuGet paketinin bir parçası olarak gönderilir ve dağıtılır.

Bu, Entity Framework'ün açık kaynak yapılmasına izin vermek için gerekliydi. Ancak, sonuç olarak, uygulamanızı Entity Framework'ün eski sürümlerinden EF 6'ya geçirmeniz veya yükseltmeniz gerektiğinde uygulamaların yeniden oluşturulması gerekecektir.

Uygulamanız EF 4.1 ve sonraki sürümlerde gönderilen DbContext kullanıyorsa geçiş işlemi basittir. Ancak uygulamanız ObjectContext ise, biraz daha fazla çalışma yapılması gerekir.

Mevcut bir uygulamayı EF6'ya yükseltmek için yapmanız gereken aşağıdaki adımlara bir göz atalım.

Step 1 - İlk adım, .NET Framework 4.5.2'yi hedeflemektir ve daha sonra projenize sağ tıklayıp özellikleri seçin.

Step 2 - Projenize tekrar sağ tıklayın ve NuGet Paketlerini Yönet'i seçin ...

Step 3- Çevrimiçi sekmesinin altında EntityFramework öğesini seçin ve Yükle'yi tıklayın. System.Data.Entity.dll'ye yönelik derleme başvurularının kaldırıldığından emin olun.

EF6 NuGet paketini yüklediğinizde, sizin için projenizden System.Data.Entity'ye yapılan tüm başvuruları otomatik olarak kaldırmalıdır.

Step 4 - EF Designer ile oluşturulmuş herhangi bir modeliniz varsa, EF6 uyumlu kod oluşturmak için kod oluşturma şablonlarını da güncellemeniz gerekecektir.

Step 5 - edmx dosyanızın altındaki Çözüm Gezgini'nde, genellikle <edmx_file_name> .tt ve <edmx_file_name> .Context.tt olarak adlandırılacak mevcut kod oluşturma şablonlarını silin.

Step 6 - Modelinizi EF Designer'da açın, tasarım yüzeyine sağ tıklayın ve Add Code Generation Item ... öğesini seçin.

Step 7 - Uygun EF 6.x kod oluşturma şablonunu ekleyin.

Ayrıca otomatik olarak EF6 uyumlu kod üretecektir.

Uygulamalarınız EF 4.1 veya sonraki bir sürümünü kullanıyorsa, DbContext ve Code First türlerinin ad alanları değişmediğinden, kodda hiçbir şeyi değiştirmeniz gerekmez.

Ancak uygulamanız Entity Framework'ün eski sürümünü kullanıyorsa, daha önce System.Data.Entity.dll'de bulunan ObjectContext gibi türler yeni ad alanlarına taşınmıştır.

Step 8 - EF6'ya göre derlemek için kullanma veya Alma yönergelerinizi güncellemeniz gerekir.

Ad alanı değişiklikleri için genel kural, System.Data. * İçindeki herhangi bir türün System.Data.Entity.Core. * 'E taşınmasıdır. Bunlardan bazıları aşağıdadır -

  • System.Data.EntityException ⇒ System.Data.Entity.Core.EntityException
  • System.Data.Objects.ObjectContext ⇒ System.Data.Entity.Core.Objects.ObjectContext;
  • System.Data.Objects.DataClasses.RelationshipManager ⇒ System.Data.Entity.Core.Objects.DataClasses.RelationshipManager;

DbContext tabanlı uygulamaların çoğu için doğrudan kullanılmadıkları için bazı türler Çekirdek ad alanlarında bulunur.

  • System.Data.EntityState ⇒ System.Data.Entity.EntityState
  • System.Data.Objects.DataClasses.EdmFunctionAttribute ⇒ System.Data.Entity.DbFunctionAttribute

Var olan Entity Framework projeniz, herhangi bir önemli değişiklik olmadan Entity Framework 6.0'da çalışacaktır.

Hevesli yükleme, bir varlık türü için yapılan sorgunun sorgunun bir parçası olarak ilgili varlıkları da yüklediği süreçtir. Hevesli yükleme,Include method.

Veritabanındaki sorgu sonuçlarıyla birlikte ilgili verilerin istenmesi anlamına gelir. Veri kaynağına yalnızca bir bağlantı yapılır, ilk sorguda daha büyük miktarda veri döndürülür.

Örneğin, öğrencileri sorgularken, kayıtlarını istekli olarak yükleyin. Öğrenciler ve kayıtları tek bir sorgu ile alınacaktır.

Kayıtları olan tüm öğrencilerin istekli yükleme kullanılarak veritabanından alındığı aşağıdaki örneğe bakalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {
         // Load all students and related enrollments
         var students = context.Students
            .Include(s ⇒ s.Enrollments).ToList();
			
         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
				
            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod derlendiğinde ve çalıştırıldığında, aşağıdaki çıktıyı alacaksınız.

ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022

Aşağıda, kullanılabilecek istekli yükleme sorgularının bazı biçimleri verilmiştir.

// Load one Student and its related enrollments

var student1 = context.Students
   .Where(s ⇒ s.FirstMidName == "Ali")
   .Include(s ⇒ s.Enrollments).FirstOrDefault();

// Load all Students and related enrollments
// using a string to specify the relationship

var studentList = context.Students
   .Include("Enrollments").ToList();

// Load one Student and its related enrollments
// using a string to specify the relationship

var student = context.Students
   .Where(s ⇒ s.FirstMidName == "Salman")
   .Include("Enrollments").FirstOrDefault();

Çoklu Düzeyler

Aynı zamanda, ilgili varlıkların birden çok düzeyini hevesle yüklemek de mümkündür. Aşağıdaki sorgular Öğrenci, Kayıtlar ve Kurs örneklerini gösterir.

// Load all Students, all related enrollments, and all related courses

var studentList = context.Students
   .Include(s ⇒ s.Enrollments.Select(c ⇒ c.Course)).ToList();

// Load all Students, all related enrollments, and all related courses
// using a string to specify the relationships

var students = context.Students
   .Include("Enrollments.Course").ToList();

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Geç yükleme, bir varlığın veya varlıklar koleksiyonunun, varlığa / varlıklara atıfta bulunan bir özelliğe ilk erişildiğinde veritabanından otomatik olarak yüklendiği işlemdir. Geç yükleme, siz özellikle talep edene kadar ilgili verilerin yüklenmesini geciktirmek anlamına gelir.

  • POCO varlık türlerini kullanırken, tembel yükleme, türetilmiş proxy türlerinin örneklerini oluşturarak ve ardından yükleme kancasını eklemek için sanal özellikleri geçersiz kılarak gerçekleştirilir.

  • Tembel yükleme hemen hemen varsayılandır.

  • Varsayılan yapılandırmayı bırakırsanız ve sorgunuzda Entity Framework'e tembel yüklemeden başka bir şey istediğinizi açıkça belirtmezseniz, alacağınız şey tembel yüklemedir.

  • Örneğin, Öğrenci varlık sınıfını kullanırken, ilgili Kayıtlar, Kayıtlar gezinme özelliğine ilk erişildiğinde yüklenecektir.

  • Gezinme özelliği genel, sanal olarak tanımlanmalıdır. Bağlam olacakNOT özellik sanal olarak tanımlanmamışsa geç yükleme yapın.

Aşağıda, Kayıtların gezinme özelliğini içeren bir Öğrenci sınıfı bulunmaktadır.

public partial class Student {

   public Student() {
      this.Enrollments = new HashSet<Enrollment>();
   }
	
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public System.DateTime EnrollmentDate { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Önce öğrenci listesinin veritabanından yüklendiği ve daha sonra ihtiyaç duyduğunuzda belirli bir öğrencinin kayıtlarını yükleyeceği basit bir örneğe bakalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         //Loading students only
         IList<Student> students = context.Students.ToList<Student>();

         foreach (var student in students) {

            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
	
            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız.

ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022
ID: 5, Name: Yan Li
       Enrollment ID: 10, Course ID: 4041
ID: 6, Name: Peggy Justice
       Enrollment ID: 11, Course ID: 1045
ID: 7, Name: Laura Norman
       Enrollment ID: 12, Course ID: 3141

Geç Yüklemeyi Kapat

Tembel yükleme ve serileştirme iyi karışmaz ve dikkatli olmazsanız, yalnızca tembel yükleme etkinleştirildiği için tüm veritabanınızı sorgulayabilirsiniz. Bir varlığı serileştirmeden önce geç yüklemeyi kapatmak iyi bir uygulamadır.

Belirli Gezinme Özellikleri için Kapatma

Enrollments koleksiyonunun geç yüklenmesi, aşağıdaki örnekte gösterildiği gibi Enrollments özelliğini sanal olmayan hale getirerek kapatılabilir.

public partial class Student { 

   public Student() { 
      this.Enrollments = new HashSet<Enrollment>(); 
   }
	
   public int ID { get; set; } 
   public string LastName { get; set; } 
   public string FirstMidName { get; set; } 
   public System.DateTime EnrollmentDate { get; set; }
   public ICollection<Enrollment> Enrollments { get; set; } 
}

Tüm Varlıklar için Kapat

Aşağıdaki örnekte gösterildiği gibi Configuration özelliğindeki bir bayrak false olarak ayarlanarak geç yükleme bağlamdaki tüm varlıklar için kapatılabilir.

public partial class UniContextEntities : DbContext { 

   public UniContextEntities(): base("name=UniContextEntities") {
      this.Configuration.LazyLoadingEnabled = false;
   }
	
   protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
      throw new UnintentionalCodeFirstException(); 
   } 
}

Geç yüklemeyi kapattıktan sonra, şimdi yukarıdaki örneği tekrar çalıştırdığınızda, Kayıtların yüklenmediğini ve sadece öğrenci verilerinin alındığını göreceksiniz.

ID: 1, Name: Ali Alexander
ID: 2, Name: Meredith Alons
ID: 3, Name: Arturo Anand
ID: 4, Name: Gytis Barzduka
ID: 5, Name: Yan Li
ID: 6, Name: Peggy Justice
ID: 7, Name: Laura Norman
ID: 8, Name: Nino Olivetto

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Geç yüklemeyi devre dışı bıraktığınızda, ilgili varlıkları tembel olarak yüklemek yine de mümkündür, ancak bunun açık bir çağrı ile yapılması gerekir.

  • Tembel yüklemeden farklı olarak, bir sorgunun ne zaman çalıştırıldığına ilişkin herhangi bir belirsizlik veya karışıklık olasılığı yoktur.

  • Bunu yapmak için ilgili varlığın girişinde Load yöntemini kullanırsınız.

  • Bire çok ilişkisi için, Koleksiyonda Load yöntemini çağırın.

  • Ve bire bir ilişki için, Referans üzerinde Load yöntemini çağırın.

Geç yüklemenin devre dışı bırakıldığı ve ardından adı Ali olan öğrencinin alındığı aşağıdaki örneğe bir göz atalım.

Öğrenci bilgileri daha sonra konsola yazılır. Koda bakarsanız, kayıt bilgileri de yazılır ancak Enrollments varlığı henüz yüklenmediğinden foreach döngüsü çalıştırılmayacaktır.

Bu Kayıtlar varlığı açıkça yüklendikten sonra şimdi öğrenci bilgileri ve kayıt bilgileri konsol penceresine yazılacaktır.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.LazyLoadingEnabled = false;

         var student = (from s in context.Students where s.FirstMidName == 
            "Ali" select s).FirstOrDefault<Student>();

         string name = student.FirstMidName + " " + student.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.WriteLine();
         Console.WriteLine("Explicitly loaded Enrollments");
         Console.WriteLine();

         context.Entry(student).Collection(s ⇒ s.Enrollments).Load();
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki örnek yürütüldüğünde, aşağıdaki çıktıyı alacaksınız. İlk olarak yalnızca öğrenci bilgileri görüntülenir ve kayıt varlıkları açıkça yüklendikten sonra, hem öğrenci hem de ilgili kayıt bilgileri görüntülenir.

ID: 1, Name: Ali Alexander
Explicitly loaded Enrollments
ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bu bölümde, model verilerini doğrulamak için ADO.NET Entity Framework içinde kullanılabilecek doğrulama tekniklerini öğrenelim. Entity Framework, istemci tarafı doğrulaması için bir kullanıcı arabirimine uygulanabilen veya sunucu tarafı doğrulaması için kullanılabilen çok çeşitli doğrulama özellikleri sağlar.

  • Entity Framework'te, veri doğrulama, bir uygulamadaki bozuk verileri yakalama çözümünün bir parçasıdır.

  • Entity Framework, çok çeşitli veri doğrulama yöntemleri kullanarak varsayılan olarak veritabanına yazılmadan önce tüm verileri doğrular.

  • Ancak Entity Framework, kullanıcı arabirimi veri doğrulamasından sonra gelir. Bu durumda, EF'nin oluşturduğu ve genel bir mesaj gösterdiği istisnaları işlemek için varlık doğrulamasına ihtiyaç vardır.

  • Hata kontrolünüzü iyileştirmek ve hata mesajlarını kullanıcıya nasıl geri iletmek için bazı veri doğrulama teknikleri vardır.

DbContext, ValidateEntity adlı bir Geçersiz Kılınabilir yönteme sahiptir. SaveChanges çağırdığınızda Entity Framework, durumu Değiştirilmemiş olan önbelleğindeki her varlık için bu yöntemi çağırır. Öğrenci Varlığı için aşağıdaki örnekte gösterildiği gibi doğrulama mantığını doğrudan buraya koyabilirsiniz.

public partial class UniContextEntities : DbContext {

   protected override System.Data.Entity.Validation
      .DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, 
      System.Collections.Generic.IDictionary<object, object> items) {

         if (entityEntry.Entity is Student) {

            if (entityEntry.CurrentValues.GetValue<string>("FirstMidName") == "") {

               var list = new List<System.Data.Entity
                  .Validation.DbValidationError>();

               list.Add(new System.Data.Entity.Validation
                  .DbValidationError("FirstMidName", "FirstMidName is required"));

               return new System.Data.Entity.Validation
                  .DbEntityValidationResult(entityEntry, list);
            }
         }

         if (entityEntry.CurrentValues.GetValue<string>("LastName") == "") {

            var list = new List<System.Data.Entity
               .Validation.DbValidationError>();

            list.Add(new System.Data.Entity.Validation
               .DbValidationError("LastName", "LastName is required"));

            return new System.Data.Entity.Validation
               .DbEntityValidationResult(entityEntry, list);
         }

         return base.ValidateEntity(entityEntry, items);
   }
}

Yukarıdaki ValidateEntity yönteminde, Öğrenci varlığı FirstMidName ve LastName özellikleri, bu özelliklerden herhangi birinin boş bir dizesi varsa kontrol edilir, ardından bir hata mesajı döndürür.

Yeni bir öğrencinin oluşturulduğu basit bir örneğe bakalım, ancak öğrencinin FirstMidName aşağıdaki kodda gösterildiği gibi boş bir dizedir.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         Console.WriteLine("Adding new Student to the database");
         Console.WriteLine();

         try {

            context.Students.Add(new Student() {
               FirstMidName = "",
               LastName = "Upston"
            });

            context.SaveChanges();
         } catch (DbEntityValidationException dbValidationEx) {

            foreach (DbEntityValidationResult entityErr in 
               dbValidationEx.EntityValidationErrors) {

               foreach (DbValidationError error in entityErr.ValidationErrors) {
                  Console.WriteLine("Error: {0}",error.ErrorMessage);
               }
            }
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki örnek derlendiğinde ve yürütüldüğünde, konsol penceresinde aşağıdaki hata mesajını alacaksınız.

Adding new Student to the database  
Error: FirstMidName is required

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework, varlıklara ve ilişkilerine yapılan değişiklikleri izleme yeteneği sağlar, böylece bağlamın SaveChanges yöntemi çağrıldığında veritabanında doğru güncelleştirmeler yapılır. Bu, Entity Framework'ün önemli bir özelliğidir.

  • Değişiklik İzleme, varlık koleksiyonuna yeni kayıt (lar) eklerken, mevcut varlıkları değiştirirken veya kaldırırken değişiklikleri izler.

  • Daha sonra tüm değişiklikler DbContext düzeyinde tutulur.

  • Bu parça değişiklikleri, DbContext nesnesi yok edilmeden önce kaydedilmezlerse kaybolur.

  • DbChangeTracker sınıfı, bağlam tarafından izlenen mevcut varlıklar hakkında size tüm bilgileri verir.

  • Herhangi bir varlığı bağlama göre izlemek için birincil anahtar özelliğine sahip olması gerekir.

Entity Framework'te değişiklik izleme varsayılan olarak etkindir. DbContext'in AutoDetectChangesEnabled özelliğini false olarak ayarlayarak da değişiklik izlemeyi devre dışı bırakabilirsiniz. Bu özellik true olarak ayarlanırsa Entity Framework varlıkların durumunu korur.

using (var context = new UniContextEntities()) {
   context.Configuration.AutoDetectChangesEnabled = true;
}

Öğrencilerin ve kayıtlarının veritabanından alındığı aşağıdaki örneğe bir göz atalım.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;
         Console.WriteLine("Retrieve Student");

         var student = (from s in context.Students where s.FirstMidName == 
            "Ali" select s).FirstOrDefault<Student>();

         string name = student.FirstMidName + " " + student.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
         Console.WriteLine();
         Console.WriteLine("Retrieve all related enrollments");

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.WriteLine();

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());

         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki örnek derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız.

Retrieve Student 
ID: 1, Name: Ali Alexander
Retrieve all related enrollments
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
Context tracking changes of 4 entity.
Entity Name: Student
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged

Tüm verilerin yalnızca veritabanından alındığını görebilirsiniz, bu nedenle durum tüm varlıklar için değişmez.

Şimdi, bir kayıt daha ekleyeceğimiz ve bir öğrenciyi veritabanından sileceğimiz başka bir basit örneğe göz atalım. Yeni kaydın eklendiği ve bir öğrencinin silindiği kod aşağıdadır.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;

         Enrollment enr = new Enrollment() { 
            StudentID = 1, CourseID = 3141 
         };

         Console.WriteLine("Adding New Enrollment");
         context.Enrollments.Add(enr);
         Console.WriteLine("Delete Student");

         var student = (from s in context.Students where s.ID == 
            23 select s).SingleOrDefault<Student>();

         context.Students.Remove(student);
         Console.WriteLine("");

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());
         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Yukarıdaki örnek derlendiğinde ve yürütüldüğünde, aşağıdaki çıktıyı alacaksınız.

Adding New Enrollment
Delete Student
Context tracking changes of 2 entity.
Entity Name: Enrollment
Status: Added
Entity Name: Student
Status: Deleted

Artık kayıt varlığının durumunun eklendi olarak ayarlandığını ve öğrenci varlığının durumunun silindiğini görebilirsiniz çünkü yeni kayıt eklendi ve bir öğrenci veritabanından kaldırıldı.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework'te, Renkli Varlık temel olarak tasarımcıdaki varlığın rengini değiştirmekle ilgilidir, böylece geliştiricilerin Visual Studio tasarımcısında ilgili varlık gruplarını tanımlaması kolaydır. Bu özellik ilk olarak Entity Framework 5.0'da tanıtıldı.

  • Bu özelliğin performans yönleriyle ilgisi yoktur.

  • Büyük ölçekli bir projeniz ve tek bir edmx dosyasında birçok varlığınız olduğunda, bu özellik varlıklarınızı farklı modüller halinde ayırmak için çok yararlıdır.

Edmx dosyasıyla çalışıyorsanız ve onu tasarımcıda açtıysanız, rengi değiştirmek için tasarım pencerelerinde bir varlık seçin. Ardından sağ tıklayın ve Özellikler'i seçin.

Özellikler penceresinde, Dolgu Rengi özelliğini seçin.

Rengi, Yeşil veya geçerli bir RGB (255, 128, 128) gibi geçerli bir renk adı kullanarak belirtin veya renk seçiciden de seçim yapabilirsiniz.

Tek seferde birden çok varlığın rengini değiştirmek için birden çok varlık seçin ve özellik penceresini kullanarak hepsi için Dolgu Rengi'ni değiştirin.

Aşağıdaki seçeneklerden herhangi birini seçerek özelliklerin formatını da değiştirebilirsiniz -

  • Ekran adı
  • Görünen Ad ve Tür

Varsayılan olarak görünen ad seçeneği seçilidir. Özellik formatını değiştirmek için tasarımcı penceresine sağ tıklayın.

Skaler Özellik Biçimi → Görünen Ad ve Tür öğesini seçin.

Artık türün adla birlikte görüntülendiğini de görebilirsiniz.

Entity Framework, bir varlık modeli oluşturmak için üç yaklaşım sağlar ve her birinin kendi artıları ve eksileri vardır.

  • Önce Kod
  • Önce Veritabanı
  • Önce Model

Bu bölümde, kod ilk yaklaşımını kısaca açıklayacağız. Bazı geliştiriciler Kodda Tasarımcı ile çalışmayı tercih ederken, diğerleri sadece kodlarıyla çalışmayı tercih eder. Bu geliştiriciler için Entity Framework, Code First olarak adlandırılan bir modelleme iş akışına sahiptir.

  • Code First modelleme iş akışı, var olmayan bir veritabanını hedefler ve Code First onu oluşturur.

  • Ayrıca boş bir veritabanınız varsa kullanılabilir ve ardından Code First ona yeni tablolar ekleyecektir.

  • Code First, modelinizi C # veya VB.Net sınıflarını kullanarak tanımlamanıza olanak tanır.

  • Ek yapılandırma, isteğe bağlı olarak sınıflarınız ve özelliklerinizdeki öznitelikler kullanılarak veya akıcı bir API kullanılarak gerçekleştirilebilir.

Neden Önce Kod?

  • Code First gerçekten bir dizi bulmaca parçasından oluşuyor. Öncelikle alan sınıflarınız.

  • Etki alanı sınıflarının Entity Framework ile ilgisi yoktur. Bunlar yalnızca işletme alanınızın öğeleridir.

  • Entity Framework, daha sonra, bu sınıflar ve veritabanınız arasındaki etkileşimi yöneten bir bağlama sahiptir.

  • Bağlam, Code First'e özgü değildir. Bir Entity Framework özelliğidir.

  • Code First, bağlamın yönettiği sınıflarınızı inceleyen bir model oluşturucu ekler ve ardından bu sınıfların ve ilişkilerin bir modeli nasıl tanımladığını ve bu modelin veritabanınızla nasıl eşleneceğini belirlemek için bir dizi kural veya kural kullanır.

  • Tüm bunlar çalışma zamanında gerçekleşir. Bu modeli asla görmeyeceksiniz, sadece hafızada.

  • Code First, isterseniz bu modeli bir veritabanı oluşturmak için kullanma yeteneğine de sahiptir.

  • Ayrıca, model değişirse, Code First Migrations adlı bir özelliği kullanarak veritabanını güncelleyebilir.

Ortam Kurulumu

EF Code First yaklaşımıyla çalışmaya başlamak için, aşağıdaki araçların sisteminize yüklenmesi gerekir.

  • Visual Studio 2013 (.net framework 4.5.2) veya sonraki sürüm.
  • MS SQL Server 2012 veya sonrası.
  • NuGet Paketi aracılığıyla Entity Framework.

NuGet Paketi aracılığıyla EF yükleyin

Step 1 - Önce Dosya → Yeni → Proje… seçeneğinden konsol uygulamasını oluşturun.

Step 2 - Sol bölmeden Windows'u ve şablon bölmesinden Konsol Uygulaması'nı seçin.

Step 3 - İsim olarak EFCodeFirstDemo girin ve Tamam'ı seçin.

Step 4 - Çözüm gezgininde projenize sağ tıklayın ve NuGet Paketlerini Yönet… öğesini seçin.

Bu, NuGet Paket Yöneticisini açacak ve EntityFramework arayacaktır. Bu, Entity Framework ile ilgili tüm paketleri arayacaktır.

Step 5- EntityFramework'ı seçin ve Yükle'ye tıklayın. Veya Araçlar menüsünden NuGet Paket Yöneticisi'ne ve ardından Paket Yöneticisi Konsolu'na tıklayın. Paket Yöneticisi Konsolu penceresinde aşağıdaki komutu girin: Install-Package EntityFramework.

Kurulum tamamlandığında, "EFCodeFirstDemo'ya 'EntityFramework 6.1.2' başarıyla yüklendi" çıktı penceresinde aşağıdaki mesajı göreceksiniz.

Kurulumdan sonra EntityFramework.dll, aşağıdaki görüntüde gösterildiği gibi projenize dahil edilecektir.

Artık Code First yaklaşımı üzerinde çalışmaya hazırsınız.

Sınıfları kullanarak çok basit bir model tanımlayalım. Bunları sadece Program.cs dosyasında tanımlıyoruz, ancak gerçek dünya uygulamasında sınıflarınızı ayrı dosyalara ve potansiyel olarak ayrı bir projeye ayıracaksınız. Aşağıda Code First yaklaşımını kullanarak oluşturacağımız bir veri modeli bulunmaktadır.

Model Oluştur

Öğrenci sınıfı için aşağıdaki kodu kullanarak Program.cs dosyasına aşağıdaki üç sınıfı ekleyin.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}
  • ID özelliği, bu sınıfa karşılık gelen veritabanı tablosunun birincil anahtar sütunu olacaktır.

  • Enrollments özelliği, bir gezinme özelliğidir. Gezinme özellikleri, bu varlıkla ilgili diğer varlıkları tutar.

  • Bu durumda, Öğrenci varlığının Enrollments özelliği, söz konusu Öğrenci varlığıyla ilişkili tüm Enrollment varlıklarını tutacaktır.

  • Gezinme özellikleri genellikle, geç yükleme gibi belirli Entity Framework işlevlerinden yararlanabilmeleri için sanal olarak tanımlanır.

  • Bir gezinme özelliği birden çok varlığı tutabiliyorsa (çoktan çoğa veya bire çok ilişkilerinde olduğu gibi), türünün ICollection gibi girişlerin eklenebileceği, silinebileceği ve güncellenebileceği bir liste olması gerekir.

Kurs sınıfı için uygulama aşağıdadır.

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Enrollments özelliği, bir gezinme özelliğidir. Bir Kurs varlığı, herhangi bir sayıda Enrollment varlığıyla ilişkilendirilebilir.

Kayıt sınıfı ve numaralandırma için uygulama aşağıdadır.

public enum Grade {
   A, B, C, D, F
}

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}
  • EnrollmentID özelliği birincil anahtar olacaktır.

  • Grade özelliği bir numaralandırmadır. Grade türü bildiriminden sonraki soru işareti, Grade özelliğinin null yapılabilir olduğunu gösterir.

  • Boş olan bir not, sıfır nottan farklıdır. Null, notun bilinmediği veya henüz atanmadığı anlamına gelir.

  • StudentID ve CourseID özellikleri yabancı anahtarlardır ve ilgili gezinme özellikleri Student ve Course'tur.

  • Bir Kayıt varlığı, bir Öğrenci ve bir Kurs varlığıyla ilişkilendirilir, bu nedenle mülk yalnızca tek bir Öğrenci ve Kurs varlığını tutabilir.

Veritabanı Bağlamı Oluşturun

Belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıf, verileri sorgulamaya ve kaydetmeye izin veren veritabanı bağlam sınıfıdır. Bu sınıfı, DbContext sınıfından türeterek ve yazılan bir DbSet göstererek oluşturabilirsiniz. modelimizdeki her sınıf için. Aşağıda, DbContext sınıfından türetilen MyContext sınıfındaki uygulama yer almaktadır.

public class MyContext : DbContext {
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Program.cs dosyasındaki kodun tamamı aşağıdadır.

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCodeFirstDemo {

   class Program {
      static void Main(string[] args) {}
   }

   public enum Grade {
      A, B, C, D, F
   }

   public class Enrollment {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Grade? Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }

   public class Student {
      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public DateTime EnrollmentDate { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class Course {
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class MyContext : DbContext {
      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }

}

Yukarıdaki kod, verileri depolamaya ve almaya başlamamız için tek ihtiyacımız olan şeydir. Biraz veri ekleyip sonra geri alalım. Ana yöntemdeki kod aşağıdadır.

static void Main(string[] args) {

   using (var context = new MyContext()) {
      // Create and save a new Students
      Console.WriteLine("Adding new students");

      var student = new Student {
         FirstMidName = "Alain", LastName = "Bomer", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student);
		
      var student1 = new Student {
         FirstMidName = "Mark", LastName = "Upston", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student1);
      context.SaveChanges();

      // Display all Students from the database
      var students = (from s in context.Students 
         orderby s.FirstMidName select s).ToList<Student>();

      Console.WriteLine("Retrieve all Students from the database:");

      foreach (var stdnt in students) {
         string name = stdnt.FirstMidName + " " + stdnt.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
      }
		
      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız.

Adding new students
Retrieve all Students from the database:
ID: 1, Name: Alain Bomer
ID: 2, Name: Mark Upston
Press any key to exit...

Şimdi akla gelen soru, veri ve bazı verileri eklediğimiz veri tabanının nerede olduğu ve sonra veri tabanından geri aldığımızdır. Geleneksel olarak, DbContext sizin için bir veritabanı oluşturmuştur.

  • Yerel bir SQL Express örneği mevcutsa, Code First bu örnekte veritabanını oluşturmuştur.

  • SQL Express kullanılamıyorsa, Code First LocalDb'yi deneyecek ve kullanacaktır.

  • Veritabanı, türetilmiş bağlamın tam nitelikli adından sonra adlandırılır.

Bizim durumumuzda, SQL Express örneği mevcuttur ve aşağıdaki görüntüde gösterildiği gibi veritabanı adı EFCodeFirstDemo.MyContext'dir.

  • Bunlar yalnızca varsayılan kurallardır ve Code First'ün kullandığı veritabanını değiştirmenin çeşitli yolları vardır.

  • Yukarıdaki görüntüde de görebileceğiniz gibi, Öğrenci, Kurslar ve Kayıtlar tablolarını oluşturmuştur ve her tablo uygun veri türü ve uzunlukta sütunlar içermektedir.

  • Sütun adları ve veri türü, ilgili alan sınıflarının özellikleriyle de eşleşir.

Veritabanı Başlatma

Yukarıdaki örnekte Code First'ün otomatik olarak bir veritabanı oluşturduğunu gördük, ancak veritabanı ve sunucunun adını değiştirmek isterseniz Code First'ün bir veritabanını başlatırken veritabanı adını ve sunucuyu nasıl belirlediğini görelim. Aşağıdaki şemaya bir göz atın.

Bağlam sınıfının temel yapıcısını aşağıdaki şekillerde tanımlayabilirsiniz.

  • Parametre Yok
  • Veri tabanı ismi
  • Bağlantı Dizesi Adı

Parametre Yok

Yukarıdaki örnekte gösterildiği gibi herhangi bir parametre olmadan bağlam sınıfının temel yapıcısını belirtirseniz, varlık çerçevesi yerel SQLEXPRESS sunucunuzda {Namespace} adıyla bir veritabanı oluşturur. {Bağlam sınıfı adı}.

Yukarıdaki örnekte, otomatik olarak oluşturulan veritabanı EFCodeFirstDemo.MyContext ismine sahiptir. İsme bakarsanız, aşağıdaki kodda gösterildiği gibi EFCodeFirstDemo'nun ad alanı ve MyContext'in bağlam sınıfı adı olduğunu göreceksiniz.

public class MyContext : DbContext {
   public MyContext() : base() {}

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Veri tabanı ismi

Veritabanı adını bağlam sınıfının temel yapıcısında bir parametre olarak iletirseniz, Code First otomatik olarak yeniden bir veritabanı oluşturur, ancak bu sefer ad, yerel SQLEXPRESS veritabanı sunucusundaki temel yapıcıda parametre olarak geçirilen ad olur .

Aşağıdaki kodda, MyContextDB temel yapıcıda parametre olarak belirtilmiştir. Uygulamanızı çalıştırırsanız, MyContextDB adlı veritabanı yerel SQL sunucunuzda oluşturulacaktır.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Bağlantı Dizesi Adı

Bu, DbContext'e SQL Express veya LocalDb dışında bir veritabanı sunucusu kullanmasını söylemenin kolay bir yoludur. App.config dosyanıza bir bağlantı dizesi koymayı seçebilirsiniz.

  • Bağlantı dizesinin adı bağlamınızın adıyla eşleşiyorsa (ad alanı nitelendirmesi olsun ya da olmasın), parametre eksi yapıcı kullanıldığında DbContext tarafından bulunacaktır.

  • Bağlantı dizesi adı bağlamınızın adından farklıysa, bağlantı dizesi adını DbContext yapıcısına ileterek DbContext'e bu bağlantıyı Code First modunda kullanmasını söyleyebilirsiniz.

public class MyContext : DbContext {
   public MyContext() : base("name = MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}
  • Yukarıdaki kodda, bağlam sınıfı bağlantı dizesinin parçacığı, temel yapıcıda bir parametre olarak belirtilmiştir.

  • Bağlantı dizesi adı "name =" ile başlamalıdır, aksi takdirde, bir veritabanı adı olarak kabul edilecektir.

  • Bu form, bağlantı dizesinin yapılandırma dosyanızda bulunmasını beklediğinizi açıkça belirtir. Verilen ada sahip bir bağlantı dizesi bulunmazsa bir istisna atılır.

<connectionStrings>
   <add name = "MyContextDB"
      connectionString = "Data Source =.;Initial Catalog = EFMyContextDB;Integrated Security = true"
      providerName = "System.Data.SqlClient"/>
</connectionStrings>
  • App.config dosyasındaki bağlantı dizesindeki veritabanı adı EFMyContextDB. CodeFirst yeni birEFMyContextDB veritabanı veya var olanı kullan EFMyContextDB yerel SQL Server'daki veritabanı.

Etki Alanı Sınıfları

Şimdiye kadar EF'in modeli kendi varsayılan kurallarını kullanarak keşfetmesine izin verdik, ancak sınıflarımızın kurallara uymadığı ve daha fazla yapılandırma gerçekleştirebilmemiz gerektiği zamanlar olacaktır. Ancak, etki alanı sınıflarınızı EF'e ihtiyaç duyduğu bilgileri sağlayacak şekilde yapılandırarak bu kuralları geçersiz kılabilirsiniz. Etki alanı sınıflarınızı yapılandırmak için iki seçenek vardır -

  • Veri Açıklamaları
  • Fluent API

Veri Açıklamaları

DataAnnotations, sınıflarınızı en sık ihtiyaç duyulan yapılandırmaları vurgulayacak şekilde yapılandırmak için kullanılır. DataAnnotations, ASP.NET MVC gibi bir dizi .NET uygulaması tarafından da anlaşılır ve bu uygulamaların istemci tarafı doğrulamaları için aynı açıklamalardan yararlanmasına izin verir.

Aşağıda, öğrenci sınıfında kullanılan veri ek açıklamaları verilmiştir.

public class Enrollment {

   [Key]
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }

   [ForeignKey("CourseID")]
   public virtual Course Course { get; set; }

   [ForeignKey("ID")]
   public virtual Student Student { get; set; }
}

Fluent API

Çoğu model yapılandırması, basit veri açıklamaları kullanılarak yapılabilir. Akıcı API, veri açıklamalarıyla mümkün olmayan bazı daha gelişmiş yapılandırmalara ek olarak, veri açıklamalarının yapabileceği her şeyi kapsayan model yapılandırmasını belirlemenin gelişmiş bir yoludur. Veri açıklamaları ve akıcı API birlikte kullanılabilir.

Fluent API'ye erişmek için DbContext'te OnModelCreating yöntemini geçersiz kılarsınız. Şimdi öğrenci tablosundaki sütun adını FirstMidName'den FirstName'e aşağıdaki kodda gösterildiği gibi yeniden adlandıralım.

public class MyContext : DbContext {

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
         .HasColumnName("FirstName");
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

DataAnnotations, en sık ihtiyaç duyulan yapılandırmaları vurgulayacak sınıfları yapılandırmak için kullanılır. DataAnnotations, ASP.NET MVC gibi bir dizi .NET uygulaması tarafından da anlaşılır; bu, bu uygulamaların istemci tarafı doğrulamaları için aynı açıklamalardan yararlanmasına olanak tanır. DataAnnotation öznitelikleri, varsayılan CodeFirst kurallarını geçersiz kılar.

System.ComponentModel.DataAnnotations sütunun boş değer atanabilirliğini veya boyutunu etkileyen aşağıdaki öznitelikleri içerir.

  • Key
  • Timestamp
  • ConcurrencyCheck
  • Required
  • MinLength
  • MaxLength
  • StringLength

System.ComponentModel.DataAnnotations.Schema ad alanı, veritabanının şemasını etkileyen aşağıdaki öznitelikleri içerir.

  • Table
  • Column
  • Index
  • ForeignKey
  • NotMapped
  • InverseProperty

Anahtar

Entity Framework, varlıkları izlemek için kullandığı bir anahtar değerine sahip her varlığa dayanır. Code First'ün bağlı olduğu kurallardan biri, Code First sınıflarının her birinde hangi özelliğin anahtar olduğunu nasıl ima ettiğidir.

  • Sözleşme, "Kimlik" adlı veya sınıf adını ve "Öğrenci Kimliği" gibi "Kimliği" birleştiren bir özelliği aramaktır.

  • Özellik, veritabanındaki bir birincil anahtar sütunuyla eşleşir.

  • Öğrenci, Kurs ve Kayıt sınıfları bu kuralı izler.

Şimdi Student sınıfının ID yerine StdntID adını kullandığını varsayalım. Code First bu kurala uyan bir özellik bulamadığında, Entity Framework'ün bir anahtar özelliğine sahip olmanız gerekliliği nedeniyle bir istisna atar. EntityKey olarak hangi özelliğin kullanılacağını belirtmek için anahtar ek açıklamasını kullanabilirsiniz.

StdntID içeren, ancak varsayılan Code First kuralına uymayan Student sınıfının aşağıdaki koduna bir göz atalım. Bu nedenle, bunun üstesinden gelmek için, onu birincil anahtar yapacak bir Anahtar özelliği eklenir.

public class Student {

   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Uygulamanızı çalıştırıp veritabanınıza SQL Server Explorer'da baktığınızda, öğrenciler tablosunda birincil anahtarın StdntID olduğunu göreceksiniz.

Entity Framework ayrıca bileşik anahtarları da destekler. Composite keysbirden fazla özellikten oluşan birincil anahtarlardır. Örneğin, birincil anahtarı LicenseNumber ve IssuingCountry'nin birleşimi olan bir DrivingLicense sınıfınız var.

public class DrivingLicense {

   [Key, Column(Order = 1)]
   public int LicenseNumber { get; set; }
   [Key, Column(Order = 2)]
   public string IssuingCountry { get; set; }
   public DateTime Issued { get; set; }
   public DateTime Expires { get; set; }
}

Bileşik anahtarlarınız olduğunda Entity Framework, anahtar özelliklerin sırasını tanımlamanızı gerektirir. Bunu, bir sipariş belirtmek için Sütun açıklamasını kullanarak yapabilirsiniz.

Zaman damgası

Code First, Zaman Damgası özelliklerini ConcurrencyCheck özellikleriyle aynı şekilde ele alır, ancak aynı zamanda kodun ilk oluşturduğu veritabanı alanının null yapılamaz olmasını da sağlar.

  • Eşzamanlılık denetimi için satır sürümü veya zaman damgası alanlarını kullanmak daha yaygındır.

  • ConcurrencyCheck ek açıklamasını kullanmak yerine, özelliğin türü bayt dizisi olduğu sürece daha özel TimeStamp ek açıklamasını kullanabilirsiniz.

  • Belirli bir sınıfta yalnızca bir zaman damgası mülkünüz olabilir.

Kurs sınıfına TimeStamp özelliğini ekleyerek basit bir örneğe bakalım -

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
   [Timestamp]
   public byte[] TStamp { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yukarıdaki örnekte görebileceğiniz gibi, Timestamp niteliği Course sınıfının Byte [] özelliğine uygulanır. Bu nedenle Code First TStamp, Courses tablosunda bir zaman damgası sütunu oluşturacaktır .

Eşzamanlılık Kontrolü

ConcurrencyCheck ek açıklaması, bir kullanıcı bir varlığı düzenlediğinde veya sildiğinde veritabanında eşzamanlılık denetimi için kullanılacak bir veya daha fazla özelliği işaretlemenize olanak tanır. EF Designer ile çalışıyorsanız, bu, bir özelliğin ConcurrencyMode ayarını Sabit olarak ayarlamakla uyumludur.

ConcurrencyCheck'in Course sınıfındaki Title özelliğine ekleyerek nasıl çalıştığına dair basit bir örneğe göz atalım.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   public string Title { get; set; }
   public int Credits { get; set; }
   [Timestamp, DataType("timestamp")]
   public byte[] TimeStamp { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yukarıdaki Course sınıfında, ConcurrencyCheck özelliği mevcut Title özelliğine uygulanır. Şimdi, Code First, aşağıdaki kodda gösterildiği gibi iyimser eşzamanlılığı kontrol etmek için güncelleme komutuna Başlık sütununu dahil edecek.

exec sp_executesql N'UPDATE [dbo].[Courses]
   SET [Title] = @0
   WHERE (([CourseID] = @1) AND ([Title] = @2))
   ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Maths',@1=1,@2=N'Calculus'
go

Gerekli Ek Açıklama

Gerekli ek açıklama, EF'ye belirli bir özelliğin gerekli olduğunu söyler. FirstMidName özelliğine Required id'nin eklendiği aşağıdaki Student sınıfına bir göz atalım. Gerekli öznitelik, EF'yi mülkün içinde veri bulunduğundan emin olmaya zorlar.

public class Student {

   [Key]
   public int StdntID { get; set; }

   [Required]
   public string LastName { get; set; }

   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yukarıdaki örnekte görüldüğü gibi, Gerekli öznitelik FirstMidName ve LastName'e uygulanır. Bu nedenle, Code First, aşağıdaki görüntüde gösterildiği gibi Öğrenciler tablosunda NOT NULL FirstMidName ve LastName sütunları oluşturacaktır.

Maksimum uzunluk

MaxLength niteliği, ek özellik doğrulamaları belirlemenize olanak tanır. Bir etki alanı sınıfının dize veya dizi türü özelliğine uygulanabilir. EF Code First, MaxLength özniteliğinde belirtildiği gibi bir sütunun boyutunu ayarlar.

MaxLength (24) özniteliğinin Title özelliğine uygulandığı aşağıdaki Course sınıfına bir göz atalım.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yukarıdaki uygulamayı çalıştırdığınızda, Code First, aşağıdaki görüntüde gösterildiği gibi CourseId tablosunda bir nvarchar (24) sütun Başlığı oluşturacaktır.

Kullanıcı 24'den fazla karakter içeren Başlığı ayarladığında, EF EntityValidationError atacaktır.

MinLength

MinLength niteliği, MaxLength'de yaptığınız gibi ek özellik doğrulamaları belirlemenize de olanak tanır. MinLength niteliği, aşağıdaki kodda gösterildiği gibi MaxLength niteliğiyle de kullanılabilir.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24) , MinLength(5)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

MinLength özniteliğinde belirtilen uzunluktan daha az veya MaxLength özniteliğinde belirtilen uzunluktan daha büyük bir Title özelliği değeri ayarlarsanız EF, EntityValidationError öğesini atar.

IP uzunluğu

StringLength ayrıca MaxLength gibi ek özellik doğrulamaları belirlemenize de olanak tanır. Tek fark, StringLength özniteliğinin yalnızca Etki Alanı sınıflarının dize türü özelliğine uygulanabilmesidir.

public class Course {

   public int CourseID { get; set; }
   [StringLength (24)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Entity Framework, StringLength özniteliği için bir özelliğin değerini de doğrular. Kullanıcı 24'den fazla karakter içeren Başlığı ayarlarsa, EF, EntityValidationError atar.

Tablo

Varsayılan Kod İlk kuralı, sınıf adına benzer bir tablo adı oluşturur. Code First'ün veritabanını oluşturmasına izin veriyorsanız ve ayrıca oluşturduğu tabloların adını değiştirmek istiyorsanız. Sonra -

  • Code First'ü mevcut bir veritabanıyla kullanabilirsiniz. Ancak, sınıfların adlarının veritabanınızdaki tabloların adlarıyla eşleşmesi her zaman geçerli değildir.

  • Tablo özniteliği bu varsayılan kuralı geçersiz kılar.

  • EF Code First, belirli bir etki alanı sınıfı için Tablo özniteliğinde belirtilen bir ada sahip bir tablo oluşturur.

Sınıfın Student olarak adlandırıldığı aşağıdaki örneğe bir göz atalım ve Code First, bunun Öğrenciler adlı bir tabloyla eşleşeceğini varsayar. Durum bu değilse, aşağıdaki kodda gösterildiği gibi Tablo özniteliğiyle tablonun adını belirtebilirsiniz.

[Table("StudentsInfo")]
public class Student {

   [Key]
   public int StdntID { get; set; }
   [Required]
   public string LastName { get; set; }
   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Artık Tablo özniteliğinin tabloyu StudentsInfo olarak belirttiğini görebilirsiniz. Tablo oluşturulduğunda, aşağıdaki görüntüde gösterildiği gibi StudentsInfo tablo adını göreceksiniz.

Yalnızca tablo adını belirleyemezsiniz, ayrıca aşağıdaki kodda gösterildiği gibi Tablo özniteliğini kullanarak tablo için bir şema da belirtebilirsiniz.

[Table("StudentsInfo", Schema = "Admin")] 
public class Student {

   [Key]
   public int StdntID { get; set; }
   [Required]
   public string LastName { get; set; }
   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yukarıdaki örnekte, tablonun yönetici şeması ile belirtildiğini görebilirsiniz. Şimdi Code First, aşağıdaki görüntüde gösterildiği gibi Yönetici şemasında StudentsInfo tablosu oluşturacaktır.

Sütun

Aynı zamanda Tablo özniteliğiyle aynıdır, ancak Tablo özniteliği tablo davranışını geçersiz kılarken Sütun özniteliği sütun davranışını geçersiz kılar. Varsayılan Kod İlk kuralı, özellik adına benzer bir sütun adı oluşturur. Code First'ün veritabanını oluşturmasına izin veriyorsanız ve ayrıca tablolarınızdaki sütunların adını değiştirmek istiyorsanız. Sonra -

  • Sütun özelliği, varsayılan kuralı geçersiz kılar.

  • EF Code First, belirli bir özellik için Sütun özniteliğinde belirtilen bir ada sahip bir sütun oluşturur.

Özelliğin FirstMidName olarak adlandırıldığı aşağıdaki örneğe bir göz atalım ve Code First bunun FirstMidName adlı bir sütuna eşleneceğini varsayar.

Durum bu değilse, aşağıdaki kodda gösterildiği gibi Sütun özniteliğiyle sütunun adını belirtebilirsiniz.

public class Student {

   public int ID { get; set; }
   public string LastName { get; set; }
   [Column("FirstName")]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Sütun özniteliğinin sütunu FirstName olarak belirttiğini görebilirsiniz. Tablo oluşturulduğunda, aşağıdaki resimde gösterildiği gibi FirstName sütun adını göreceksiniz.

Dizin

Index özniteliği Entity Framework 6.1'de tanıtıldı. Daha önceki bir sürümü kullanıyorsanız, bu bölümdeki bilgiler geçerli değildir.

  • IndexAttribute kullanarak bir veya daha fazla sütunda bir dizin oluşturabilirsiniz.

  • Özniteliğin bir veya daha fazla özelliğe eklenmesi, EF'nin veritabanını oluşturduğunda veritabanında karşılık gelen dizini oluşturmasına neden olur.

  • Dizinler, çoğu durumda verilerin daha hızlı ve verimli bir şekilde alınmasını sağlar. Ancak, bir tablonun veya görünümün dizinlerle aşırı yüklenmesi, eklemeler veya güncellemeler gibi diğer işlemlerin performansını istenmeyen bir şekilde etkileyebilir.

  • Dizin oluşturma, veritabanından verileri sorgulamak için gereken süreyi azaltarak Code First uygulamanızın performansını artırabileceğiniz Entity Framework'teki yeni özelliktir.

  • Dizin özniteliğini kullanarak veritabanınıza dizinler ekleyebilir ve senaryonuza en uygun dizini elde etmek için varsayılan Benzersiz ve Kümelenmiş ayarları geçersiz kılabilirsiniz.

  • Varsayılan olarak, dizin IX_ <özellik adı> olarak adlandırılacaktır.

Krediler için Ders sınıfına Index niteliğinin eklendiği aşağıdaki koda bir göz atalım.

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Index özniteliğinin Credits özelliğine uygulandığını görebilirsiniz. Tablo oluşturulduğunda, Endekslerde IX_Credits göreceksiniz.

Varsayılan olarak dizinler benzersiz değildir, ancak IsUniquebir dizinin benzersiz olması gerektiğini belirtmek için adlandırılmış parametre. Aşağıdaki örnek, aşağıdaki kodda gösterildiği gibi benzersiz bir dizin sunar.

public class Course {
   public int CourseID { get; set; }
   [Index(IsUnique = true)]
	
   public string Title { get; set; }
   [Index]
	
   public int Credits { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Yabancı anahtar

Code First kuralı, modelinizdeki en yaygın ilişkilerle ilgilenecektir, ancak yardıma ihtiyaç duyduğu bazı durumlar vardır. Örneğin, Öğrenci sınıfındaki anahtar özelliğinin adını değiştirerek, Kayıt sınıfıyla ilişkisiyle ilgili bir sorun yarattı.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

public class Student {
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Veritabanını oluştururken Code First, Enrollment sınıfındaki StudentID özelliğini görür ve Student sınıfına bir yabancı anahtar olarak bir sınıf adı ve "ID" ile eşleştiği kuralıyla tanır. Ancak, Student sınıfında StudentID özelliği yoktur, ancak StdntID özelliği Öğrenci sınıfıdır.

Bunun çözümü, Kayıt'ta bir gezinti özelliği oluşturmak ve Code First'ün aşağıdaki kodda gösterildiği gibi iki sınıf arasındaki ilişkiyi nasıl oluşturacağını anlamasına yardımcı olmak için ForeignKey DataAnnotation'ı kullanmaktır.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
	
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }
   [ForeignKey("StudentID")]
	
   public virtual Student Student { get; set; }
}

Artık ForeignKey özniteliğinin gezinti özelliğine uygulandığını görebilirsiniz.

Eşlenmemiş

Varsayılan Code First kuralları olarak, desteklenen bir veri türünde olan ve alıcılar ve ayarlayıcıları içeren her özellik veritabanında temsil edilir. Ancak uygulamalarınızda durum her zaman böyle değildir. NotMapped özniteliği bu varsayılan kuralı geçersiz kılar. Örneğin, Öğrenci sınıfında BabaAdı gibi bir özelliğiniz olabilir, ancak bunun depolanması gerekmez. Aşağıdaki kodda gösterildiği gibi, veritabanında bir sütun oluşturmak istemediğiniz bir BabaAdı özelliğine NotMapped özniteliğini uygulayabilirsiniz.

public class Student {
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
	
   public DateTime EnrollmentDate { get; set; }
   [NotMapped]

   public int FatherName { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

NotMapped özniteliğinin FatherName özelliğine uygulandığını görebilirsiniz. Tablo oluşturulduğunda, BabaAdı sütununun bir veritabanında oluşturulmayacağını, ancak Öğrenci sınıfında mevcut olduğunu göreceksiniz.

Code First, Student sınıfının Address ve Age özelliklerinin aşağıdaki örneğinde gösterildiği gibi alıcıları veya ayarlayıcıları olmayan bir özellik için bir sütun oluşturmaz.

InverseProperty

InverseProperty, sınıflar arasında birden çok ilişkiniz olduğunda kullanılır. Kayıt sınıfında, Mevcut Kursu ve Önceki Kursu kimin kaydettirdiğini takip etmek isteyebilirsiniz. Enrollment sınıfı için iki gezinme özelliği ekleyelim.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course CurrCourse { get; set; }
   public virtual Course PrevCourse { get; set; }
   public virtual Student Student { get; set; }
}

Benzer şekilde, bu özelliklerin referans aldığı Course sınıfını da eklemeniz gerekir. Course sınıfı, tüm geçerli ve önceki kayıtları içeren Enrollment sınıfına geri dönme gezinme özelliklerine sahiptir.

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }
   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }
   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

Code First, yabancı anahtar özelliği yukarıdaki sınıflarda gösterildiği gibi belirli bir sınıfa dahil edilmemişse, {Sınıf Adı} _ {Birincil Anahtar} yabancı anahtar sütununu oluşturur. Veritabanı oluşturulduğunda aşağıdaki yabancı anahtarları göreceksiniz.

Gördüğünüz gibi, Kod ilk önce iki sınıftaki özellikleri kendi başına eşleştiremez. Kayıtlar için veritabanı tablosunda CurrCourse ve PrevCourse için bir yabancı anahtara sahip olmalıdır, ancak Code First dört yabancı anahtar özelliği oluşturacaktır.

  • CurrCourse _CourseID
  • PrevCourse _CourseID
  • Course_CourseID ve
  • Course_CourseID1

Bu sorunları gidermek için, özelliklerin hizalamasını belirtmek için InverseProperty detaylandırmasını kullanabilirsiniz.

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }
   [InverseProperty("CurrCourse")]

   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }
   [InverseProperty("PrevCourse")]

   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

Gördüğünüz gibi InverseProperty özniteliği, Enrollment sınıfının hangi referans özelliğine ait olduğu belirtilerek yukarıdaki Course sınıfında uygulanır. Şimdi, Code First bir veritabanı oluşturacak ve aşağıdaki görüntüde gösterildiği gibi Kayıtlar tablosunda yalnızca iki yabancı anahtar sütunu oluşturacaktır.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Fluent API, veri ek açıklamalarıyla mümkün olmayan bazı daha gelişmiş yapılandırmalara ek olarak veri açıklamalarının yapabileceği her şeyi kapsayan model yapılandırmasını belirlemenin gelişmiş bir yoludur. Veri açıklamaları ve akıcı API birlikte kullanılabilir, ancak Code First, Fluent API> veri açıklamaları> varsayılan kurallara öncelik verir.

  • Fluent API, alan sınıflarınızı yapılandırmanın başka bir yoludur.

  • Code First Fluent API'ye en yaygın olarak türetilmiş DbContext'inizdeki OnModelCreating yöntemini geçersiz kılarak erişilir.

  • Fluent API, konfigürasyon için DataAnnotations'tan daha fazla işlevsellik sağlar. Fluent API, aşağıdaki eşleme türlerini destekler.

Bu bölümde, Student, Course ve Enrollment sınıflarını ve aşağıdaki kodda gösterildiği gibi MyContext adıyla bir bağlam sınıfını içeren basit örnekle devam edeceğiz.

using System.Data.Entity; 
using System.Linq; 
using System.Text;
using System.Threading.Tasks;  

namespace EFCodeFirstDemo {

   class Program {
      static void Main(string[] args) {}
   }
   
   public enum Grade {
      A, B, C, D, F
   }

   public class Enrollment {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Grade? Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }

   public class Student {
      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
		
      public DateTime EnrollmentDate { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class Course {
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class MyContext : DbContext {
      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }

}

Fluent API'ye erişmek için DbContext'te OnModelCreating yöntemini geçersiz kılmanız gerekir. Öğrenci tablosundaki sütun adını FirstMidName'den FirstName'e aşağıdaki kodda gösterildiği gibi yeniden adlandıracağımız basit bir örneğe bakalım.

public class MyContext : DbContext {

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
      .HasColumnName("FirstName");}

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
}

DbModelBuilder, CLR sınıflarını bir veritabanı şemasına eşlemek için kullanılır. Tüm alan sınıflarınızı yapılandırabileceğiniz ana sınıftır. Bir Varlık Veri Modeli (EDM) oluşturmaya yönelik bu kod merkezli yaklaşım, Önce Kod olarak bilinir.

Fluent API, çeşitli Code First kurallarını geçersiz kılmak için varlıkları ve özelliklerini yapılandırmak için bir dizi önemli yöntem sağlar. Bunlardan bazıları aşağıdadır.

Sr. No. Yöntem Adı ve Açıklaması
1

ComplexType<TComplexType>

Bir türü modelde karmaşık bir tür olarak kaydeder ve karmaşık türü yapılandırmak için kullanılabilecek bir nesne döndürür. Bu yöntem, aynı tipin birden çok yapılandırma satırı gerçekleştirmesi için birden çok kez çağrılabilir.

2

Entity<TEntityType>

Bir varlık türünü modelin bir parçası olarak kaydeder ve varlığı yapılandırmak için kullanılabilecek bir nesne döndürür. Bu yöntem, aynı varlığın birden çok yapılandırma satırı gerçekleştirmesi için birden çok kez çağrılabilir.

3

HasKey<TKey>

Bu varlık türü için birincil anahtar özelliklerini yapılandırır.

4

HasMany<TTargetEntity>

Bu varlık türünden birçok ilişkiyi yapılandırır.

5

HasOptional<TTargetEntity>

Bu varlık türünden isteğe bağlı bir ilişki yapılandırır. Varlık türünün örnekleri, bu ilişki belirtilmeden veritabanına kaydedilebilir. Veritabanındaki yabancı anahtar null yapılabilir.

6

HasRequired<TTargetEntity>

Bu varlık türünden gerekli bir ilişkiyi yapılandırır. Varlık türünün örnekleri, bu ilişki belirtilmediği sürece veritabanına kaydedilemez. Veritabanındaki yabancı anahtar null yapılamaz.

7

Ignore<TProperty>

Veritabanına eşlenmemesi için bir özelliği modelden hariç tutar. (StructuralTypeConfiguration <TStructuralType> öğesinden devralındı)

8

Property<T>

Bu tür üzerinde tanımlanan bir yapı özelliğini yapılandırır. (StructuralTypeConfiguration <TStructuralType> öğesinden devralındı)

9

ToTable(String)

Bu varlık türünün eşlendiği tablo adını yapılandırır.

Fluent API, ister veritabanıyla nasıl eşleştikleri veya birbirleriyle nasıl ilişkili oldukları hakkında bir şeyler değiştirmek isteyip istemediğinizi, varlıklarınızı veya özelliklerini yapılandırmanıza izin verir. Yapılandırmaları kullanarak etkileyebileceğiniz çok çeşitli eşleme ve modelleme vardır. Aşağıda, Fluent API'nin desteklediği ana eşleme türleri verilmiştir -

  • Varlık Eşleme
  • Özellikler Eşleme

Varlık Eşleme

Varlık eşleme, Entity Framework'ün sınıfların veritabanlarına nasıl eşlendiğini anlamasını etkileyecek bazı basit eşlemelerden ibarettir. Tüm bunları veri açıklamalarında tartıştık ve burada Fluent API kullanarak aynı şeyleri nasıl başaracağımızı göreceğiz.

  • Dolayısıyla, bu konfigürasyonları eklemek için alan sınıflarına girmek yerine, bunu bağlamın içinde yapabiliriz.

  • İlk şey, modelBuilder'ın birlikte çalışmasını sağlayan OnModelCreating yöntemini geçersiz kılmaktır.

Varsayılan Şema

Veritabanı oluşturulduğunda varsayılan şema dbo şeklindedir. Tüm tablolar, saklı yordamlar vb. İçin kullanılacak veritabanı şemasını belirtmek için DbModelBuilder'da HasDefaultSchema yöntemini kullanabilirsiniz.

Yönetici şemasının uygulandığı aşağıdaki örneğe bir göz atalım.

public class MyContext : DbContext {
   public MyContext() : base("name = MyContextDB") {}

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      //Configure default schema
      modelBuilder.HasDefaultSchema("Admin");
   }
	
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Varlığı Tabloya Eşle

Varsayılan kural ile Code First, dersler, Kayıtlar ve Öğrenciler gibi bağlam sınıfındaki DbSet özelliklerinin adıyla veritabanı tabloları oluşturacaktır. Ancak farklı tablo adları istiyorsanız, bu kuralı geçersiz kılabilir ve aşağıdaki kodda gösterildiği gibi DbSet özelliklerinden farklı bir tablo adı sağlayabilirsiniz.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Map entity to table
   modelBuilder.Entity<Student>().ToTable("StudentData");
   modelBuilder.Entity<Course>().ToTable("CourseDetail");
   modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo");
}

Veritabanı oluşturulduğunda, OnModelCreating yönteminde belirtildiği gibi tablo adını göreceksiniz.

Varlık Bölme (Varlığı Birden Çok Tabloya Eşle)

Varlık Bölme, birden çok tablodan gelen verileri tek bir sınıfta birleştirmenize olanak tanır ve yalnızca aralarında bire bir ilişki olan tablolarla kullanılabilir. Öğrenci bilgilerinin iki tabloya eşleştirildiği aşağıdaki örneğe bir göz atalım.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Map entity to table
   modelBuilder.Entity<Student>().Map(sd ⇒ {
      sd.Properties(p ⇒ new { p.ID, p.FirstMidName, p.LastName });
      sd.ToTable("StudentData");
   })

   .Map(si ⇒ {
      si.Properties(p ⇒ new { p.ID, p.EnrollmentDate });
      si.ToTable("StudentEnrollmentInfo");
   });

   modelBuilder.Entity<Course>().ToTable("CourseDetail");
   modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo");
}

Yukarıdaki kodda, Map yöntemini kullanarak bazı özellikleri StudentData tablosuna ve bazı özellikleri StudentEnrollmentInfo tablosuna eşleyerek Student varlığının aşağıdaki iki tabloya bölündüğünü görebilirsiniz.

  • StudentData - Student FirstMidName ve Last Name içerir.

  • StudentEnrollmentInfo - EnrollmentDate içerir.

Veritabanı oluşturulduğunda, aşağıdaki görüntüde gösterildiği gibi veritabanınızda aşağıdaki tabloları görürsünüz.

Özellikler Eşleme

Özellik yöntemi, bir varlığa veya karmaşık türe ait her bir özelliğin özniteliklerini yapılandırmak için kullanılır. Özellik yöntemi, belirli bir özellik için bir yapılandırma nesnesi elde etmek için kullanılır. Etki alanı sınıflarınızın özelliklerini Fluent API kullanarak da eşleyebilir ve yapılandırabilirsiniz.

Birincil Anahtarı Yapılandırma

Birincil anahtarlar için varsayılan kural şunlardır:

  • Sınıf, adı "ID" veya "Id" olan bir özelliği tanımlar
  • Sınıf adı ve ardından "ID" veya "Id"

Sınıfınız, aşağıdaki Öğrenci sınıfı kodunda gösterildiği gibi birincil anahtar için varsayılan kuralları takip etmiyorsa -

public class Student {
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Ardından, bir özelliği açıkça birincil anahtar olarak ayarlamak için HasKey yöntemini aşağıdaki kodda gösterildiği gibi kullanabilirsiniz -

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
	
   // Configure Primary Key
   modelBuilder.Entity<Student>().HasKey<int>(s ⇒ s.StdntID); 
}

Sütunu Yapılandır

Entity Framework'te, Code First varsayılan olarak aynı ada, sıraya ve veri türüne sahip bir özellik için bir sütun oluşturur. Ancak, aşağıdaki kodda gösterildiği gibi bu kuralı da geçersiz kılabilirsiniz.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Configure EnrollmentDate Column
   modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate)
	
   .HasColumnName("EnDate")
   .HasColumnType("DateTime")
   .HasColumnOrder(2);
}

MaxLength Özelliğini Yapılandırma

Aşağıdaki örnekte, Kurs Başlığı özelliği 24 karakterden uzun olmamalıdır. Kullanıcı 24 karakterden uzun bir değer belirttiğinde, kullanıcı bir DbEntityValidationException istisnası alır.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
   modelBuilder.Entity<Course>().Property(p ⇒ p.Title).HasMaxLength(24);
}

Null veya NotNull Özelliğini Yapılandırma

Aşağıdaki örnekte, Ders Başlığı özelliği gereklidir, bu nedenle IsRequired yöntemi NotNull sütunu oluşturmak için kullanılır. Benzer şekilde, Student EnrollmentDate isteğe bağlıdır, bu nedenle aşağıdaki kodda gösterildiği gibi bu sütunda boş bir değere izin vermek için IsOptional yöntemini kullanacağız.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
   modelBuilder.Entity<Course>().Property(p ⇒ p.Title).IsRequired();
   modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate).IsOptional();
	
   //modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
   //.HasColumnName("FirstName"); 
}

İlişkileri Yapılandırma

Veritabanları bağlamında bir ilişki, bir tablo diğer tablonun birincil anahtarına başvuran bir yabancı anahtara sahip olduğunda iki ilişkisel veritabanı tablosu arasında var olan bir durumdur. Code First ile çalışırken, etki alanı CLR sınıflarınızı tanımlayarak modelinizi tanımlarsınız. Varsayılan olarak, Entity Framework sınıflarınızı veritabanı şemasına eşlemek için Code First kurallarını kullanır.

  • Code First adlandırma kurallarını kullanırsanız, çoğu durumda, yabancı anahtarlara ve gezinme özelliklerine dayalı olarak tablolarınız arasında ilişkiler kurmak için Code First'e güvenebilirsiniz.

  • Bu kurallara uymazlarsa, sınıflar arasındaki ilişkileri ve bu ilişkilerin Code First'e yapılandırmalar eklerken veritabanında nasıl gerçekleştirildiğini etkilemek için kullanabileceğiniz yapılandırmalar da vardır.

  • Bazıları veri açıklamalarında mevcuttur ve bazı daha karmaşık olanları bir Fluent API ile uygulayabilirsiniz.

Bire Bir İlişkiyi Yapılandırın

Modelinizde bire bir ilişki tanımladığınızda, her sınıfta bir referans gezinme özelliği kullanırsınız. Veritabanında, her iki tabloda da ilişkinin her iki tarafında yalnızca bir kayıt olabilir. Her birincil anahtar değeri, ilgili tablodaki yalnızca bir kayıtla (veya kayıt yok) ilgilidir.

  • İlgili sütunların her ikisi de birincil anahtar ise veya benzersiz kısıtlamalara sahipse, bire bir ilişki oluşturulur.

  • Bire bir ilişkide, birincil anahtar ek olarak yabancı anahtar görevi görür ve her iki tablo için ayrı yabancı anahtar sütunu yoktur.

  • Bu tür bir ilişki yaygın değildir çünkü bu şekilde ilgili çoğu bilgi tek bir tabloda olacaktır.

Bire bir ilişki oluşturmak için modelimize başka bir sınıf ekleyeceğimiz aşağıdaki örneğe bir göz atalım.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual StudentLogIn StudentLogIn { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class StudentLogIn {
   [Key, ForeignKey("Student")]
   public int ID { get; set; }
   public string EmailID { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Yukarıdaki kodda görebileceğiniz gibi, Key ve ForeignKey öznitelikleri StudentLogIn sınıfında ID özelliği için, onu Primary Key ve Foreign Key olarak işaretlemek için kullanılmaktadır.

Fluent API kullanarak Student ve StudentLogIn arasında bire sıfır veya bir ilişki yapılandırmak için, aşağıdaki kodda gösterildiği gibi OnModelCreating yöntemini geçersiz kılmanız gerekir.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure ID as PK for StudentLogIn
   modelBuilder.Entity<StudentLogIn>()
   .HasKey(s ⇒ s.ID);

   // Configure ID as FK for StudentLogIn
   modelBuilder.Entity<Student>()
   
   .HasOptional(s ⇒ s.StudentLogIn) //StudentLogIn is optional
   .WithRequired(t ⇒ t.Student); // Create inverse relationship
}

Çoğu durumda Entity Framework, hangi türün bağımlı olduğunu ve hangisinin bir ilişkideki asıl öğe olduğunu çıkarabilir. Ancak, ilişkinin her iki ucu da gerekli olduğunda veya her iki taraf da isteğe bağlı olduğunda, Entity Framework bağımlı ve sorumlusu tanımlayamaz. İlişkinin her iki ucu da gerekli olduğunda, HasRequired'ı aşağıdaki kodda gösterildiği gibi kullanabilirsiniz.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure ID as PK for StudentLogIn
   modelBuilder.Entity<StudentLogIn>()
   .HasKey(s ⇒ s.ID);

   // Configure ID as FK for StudentLogIn
   modelBuilder.Entity<Student>()
   .HasRequired(r ⇒ r.Student)
   .WithOptional(s ⇒ s.StudentLogIn);  
}

Veritabanı oluşturulduğunda, aşağıdaki resimde gösterildiği gibi ilişkinin oluşturulduğunu göreceksiniz.

Bire Çoğa İlişkiyi Yapılandırın

Birincil anahtar tablosu, ilgili tablodaki hiçbir kayıt, bir veya birden fazla kayıtla ilgili olan yalnızca bir kayıt içerir. Bu, en yaygın kullanılan ilişki türüdür.

  • Bu ilişki türünde, A tablosundaki bir satır, B tablosunda birçok eşleşen satıra sahip olabilir, ancak B tablosundaki bir satır, A tablosunda yalnızca bir eşleşen satıra sahip olabilir.

  • Yabancı anahtar, ilişkinin birçok sonunu temsil eden tabloda tanımlanır.

  • Örneğin, yukarıdaki diyagramda Öğrenci ve Kayıt tabloları bire bir ilişkiye sahiptir, her öğrencinin birçok kaydı olabilir, ancak her kayıt yalnızca bir öğrenciye aittir.

Aşağıda, bire çok ilişkisi olan Öğrenci ve Kayıt bulunmaktadır, ancak Kayıt tablosundaki yabancı anahtar varsayılan Kod İlk kurallarını izlememektedir.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
	
   //StdntID is not following code first conventions name
   public int StdntID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual StudentLogIn StudentLogIn { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Bu durumda, Fluent API kullanarak bire çok ilişkisini yapılandırmak için, aşağıdaki kodda gösterildiği gibi HasForeignKey yöntemini kullanmanız gerekir.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Configure FK for one-to-many relationship
   modelBuilder.Entity<Enrollment>()

   .HasRequired<Student>(s ⇒ s.Student)
   .WithMany(t ⇒ t.Enrollments)
   .HasForeignKey(u ⇒ u.StdntID);  
}

Veritabanı oluşturulduğunda, aşağıdaki görüntüdeki gibi ilişkinin oluşturulduğunu göreceksiniz.

Yukarıdaki örnekte HasRequired yöntemi Öğrenci gezinti özelliğinin Null olması gerektiğini belirtir. Bu nedenle, her Kayıt eklediğinizde veya güncellediğinizde Kayıt varlığına sahip Öğrenci atamalısınız. Bunu halletmek için HasRequired yöntemi yerine HasOptional yöntemini kullanmamız gerekiyor.

Çoktan Çoğa İlişkiyi Yapılandırma

Her iki tablodaki her kayıt, diğer tablodaki herhangi bir sayıda kayıtla (veya hiçbir kayıtla) ilgili olabilir.

  • Bu tür bir ilişki, birincil anahtarı hem tablo A hem de tablo B'deki yabancı anahtarlardan oluşan bağlantı tablosu adı verilen üçüncü bir tablo tanımlayarak oluşturabilirsiniz.

  • Örneğin, Öğrenci tablosu ve Kurs tablosunun çoka çok ilişkisi vardır.

Aşağıdakiler, Öğrenci ve Kursun çoktan çok ilişkiye sahip olduğu Öğrenci ve Kurs sınıflarıdır, çünkü her iki sınıfın da koleksiyon özellikleri olan Öğrenciler ve Kurslar gezinme özelliklerine sahiptir. Başka bir deyişle, bir varlığın başka bir varlık koleksiyonu vardır.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Course> Courses { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Student> Students { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Öğrenci ve Kurs arasındaki çoktan çoğa ilişkisini yapılandırmak için aşağıdaki kodda gösterildiği gibi Fluent API'yi kullanabilirsiniz.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure many-to-many relationship
   modelBuilder.Entity<Student>()
   .HasMany(s ⇒ s.Courses) 
   .WithMany(s ⇒ s.Students);
}

Varsayılan Code First kuralları, veritabanı oluşturulduğunda bir birleştirme tablosu oluşturmak için kullanılır. Sonuç olarak, StudentCourses tablosu, aşağıdaki görüntüde gösterildiği gibi Course_CourseID ve Student_ID sütunlarıyla oluşturulur.

Birleştirme tablosu adını ve tablodaki sütunların adlarını belirtmek isterseniz, Map yöntemini kullanarak ek yapılandırma yapmanız gerekir.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure many-to-many relationship 
   modelBuilder.Entity<Student>()

   .HasMany(s ⇒ s.Courses)
   .WithMany(s ⇒ s.Students)
   
   .Map(m ⇒ {
      m.ToTable("StudentCoursesTable");
      m.MapLeftKey("StudentID");
      m.MapRightKey("CourseID");
   }); 
}

Veritabanının ne zaman oluşturulduğunu, tablo ve sütun adlarının yukarıdaki kodda belirtildiği gibi oluşturulduğunu görebilirsiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework'te Seed, EF 4.1'de tanıtılmıştır ve veritabanı başlatıcılarla çalışır. Genel fikirSeed MethodVerileri, Code First tarafından oluşturulan veya Geçişler tarafından geliştirilen bir veritabanında başlatmaktır. Bu veriler genellikle test verileridir, ancak aynı zamanda bilinen Öğrenciler, Kurslar, vb. Listeleri gibi referans verileri de olabilir. Veriler başlatıldığında, aşağıdakileri yapar -

  • Hedef veritabanının zaten var olup olmadığını kontrol eder.
  • Varsa, geçerli Code First modeli, veritabanındaki meta verilerde depolanan modelle karşılaştırılır.
  • Geçerli model, veritabanındaki modelle eşleşmezse veritabanı bırakılır.
  • Veritabanı düşürüldüyse veya ilk etapta mevcut değilse oluşturulur.
  • Veritabanı oluşturulmuşsa, başlatıcı Seed yöntemi çağrılır.

Seed yöntemi, veritabanı bağlam nesnesini bir giriş parametresi olarak alır ve yöntemdeki kod, veritabanına yeni varlıklar eklemek için bu nesneyi kullanır. Veritabanınıza veri yerleştirmek için Tohum yöntemini geçersiz kılmanız gerekir. Varsayılan verilerin bir kısmının dahili bir sınıfta veritabanına başlatıldığı aşağıdaki örneğe bir göz atalım.

private class UniDBInitializer<T> : DropCreateDatabaseAlways<MyContext> {

   protected override void Seed(MyContext context) {

      IList<Student> students = new List<Student>();

      students.Add(new Student() {
         FirstMidName = "Andrew", 
         LastName = "Peters", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      students.Add(new Student() {
         FirstMidName = "Brice", 
         LastName = "Lambson", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      students.Add(new Student() {
         FirstMidName = "Rowan", 
         LastName = "Miller", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      foreach (Student student in students)
      context.Students.Add(student);
      base.Seed(context);
   }
}

Yukarıdaki kodda öğrenci tablosu başlatılmıştır. Bu DB başlatıcı sınıfını aşağıdaki kodda gösterildiği gibi bağlam sınıfında ayarlamanız gerekir.

public MyContext() : base("name=MyContextDB") {
   Database.SetInitializer<MyContext>(new UniDBInitializer<MyContext>());
}

Aşağıda, DB başlatıcı sınıfını da içeren MyContext sınıfının tam sınıf uygulaması yer almaktadır.

public class MyContext : DbContext {

   public MyContext() : base("name=MyContextDB") {
      Database.SetInitializer<MyContext>(new UniDBInitializer<MyContext>());
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
	
   private class UniDBInitializer<T> : DropCreateDatabaseAlways<MyContext> {

      protected override void Seed(MyContext context) {

         IList<Student> students = new List<Student>();
			
         students.Add(new Student() {
            FirstMidName = "Andrew", 
            LastName = "Peters", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString()) 
         });

         students.Add(new Student() {
            FirstMidName = "Brice", 
            LastName = "Lambson", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         students.Add(new Student() {
            FirstMidName = "Rowan", 
            LastName = "Miller", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         foreach (Student student in students)
         context.Students.Add(student);
         base.Seed(context);
      }
   } 
}

Yukarıdaki örnek derlendiğinde ve yürütüldüğünde, verileri aşağıdaki görüntüde gösterildiği gibi bir veritabanında görebilirsiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework 4.3, modeliniz zaman içinde değiştikçe veritabanı şemasını aşamalı olarak geliştirmenize olanak tanıyan yeni bir Code First Migrations özelliği içerir. Çoğu geliştirici için bu, modeliniz değiştiğinde veritabanını manuel olarak güncellemenizi veya bırakıp yeniden oluşturmanızı gerektiren 4.1 ve 4.2 sürümlerindeki veritabanı başlatıcı seçeneklerine göre büyük bir gelişmedir.

  • Entity Framework 4.3'ten önce, veritabanınızda zaten verileriniz (çekirdek veriler dışında) veya mevcut Depolanan Prosedürler, tetikleyiciler vb. Varsa, bu stratejiler tüm veritabanını bırakmak ve yeniden oluşturmak için kullanılır, böylece verileri ve diğer DB'leri kaybedersiniz. nesneler.

  • Taşıma ile, modeliniz herhangi bir mevcut veriyi veya diğer veritabanı nesnelerini kaybetmeden değiştiğinde veritabanı şemasını otomatik olarak güncelleyecektir.

  • MigrateDatabaseToLatestVersion adlı yeni bir veritabanı başlatıcısı kullanır.

İki tür Göç vardır -

  • Otomatik Geçiş
  • Kod tabanlı Geçiş

Otomatik Geçiş

Otomatik Geçiş ilk olarak Varlık çerçevesi 4.3'te tanıtıldı. Otomatikleştirilmiş geçişte, kod dosyasında veritabanı geçişini manuel olarak işlemeniz gerekmez. Örneğin, her değişiklik için alan sınıflarınızda da değişiklik yapmanız gerekecektir. Ancak otomatik geçişte, bunu yapmak için Paket Yöneticisi Konsolunda bir komut çalıştırmanız yeterlidir.

Aşağıdaki otomatik geçiş sürecine adım adım bir göz atalım.

Code First yaklaşımını kullandığınızda, uygulamanız için bir veritabanınız olmaz.

Bu örnekte, aşağıdaki kodda gösterildiği gibi Öğrenci, Kurs ve Kayıt gibi 3 temel sınıfımızla başlayacağız.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Aşağıdaki bağlam sınıfıdır.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Uygulamayı çalıştırmadan önce, otomatik geçişi etkinleştirmeniz gerekir.

Step 1 - Araçlar → NuGet Paket Yöneticisi → Paket Yöneticisi Konsolundan Paket Yöneticisi Konsolunu açın.

Step 2 - Otomatik geçişi etkinleştirmek için Paket Yöneticisi Konsolu'nda aşağıdaki komutu çalıştırın.

PM> enable-migrations -EnableAutomaticMigrations:$true

Step 3 - Komut başarılı bir şekilde çalıştığında, aşağıdaki kodda gösterildiği gibi projenizin Migration klasöründe dahili bir mühürlenmiş Configuration sınıfı oluşturur.

namespace EFCodeFirstDemo.Migrations {

   using System;
   using System.Data.Entity;
   using System.Data.Entity.Migrations;
   using System.Linq;
	
   internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> {

      public Configuration() {
         AutomaticMigrationsEnabled = true;
         ContextKey = "EFCodeFirstDemo.MyContext";
      }

      protected override void Seed(EFCodeFirstDemo.MyContext 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" }
         //  );
      }
   }
}

Step 4 - Yeni veritabanı başlatma stratejisi MigrateDatabaseToLatestVersion ile bağlam sınıfındaki veritabanı başlatıcıyı ayarlayın.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, 
         EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 5- Otomatik taşımayı ayarladınız. Uygulamanızı çalıştırdığınızda, modeli değiştirdiğinizde otomatik olarak geçişi halledecektir.

Step 6- Gördüğünüz gibi, __MigrationHistory bir sistem tablosu da veritabanınızda diğer tablolarla birlikte oluşturulur. __MigrationHistory'de, otomatikleştirilmiş geçiş, veritabanı değişikliklerinin geçmişini korur.

Step 7- Etki alanı sınıfınız olarak başka bir varlık sınıfı eklediğinizde ve uygulamanızı çalıştırdığınızda, veritabanınızda tabloyu oluşturacaktır. Aşağıdaki StudentLogIn sınıfını ekleyelim.

public class StudentLogIn {
   [Key, ForeignKey("Student")]
   public int ID { get; set; }
   public string EmailID { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Step 8 - Yukarıda belirtilen sınıf için DBSet'i aşağıdaki kodda gösterildiği gibi bağlam sınıfınıza eklemeyi unutmayın.

public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }

Step 9 - Uygulamanızı tekrar çalıştırın ve StudentsLogIn tablosunun veritabanınıza eklendiğini göreceksiniz.

Otomatikleştirilmiş geçişler için yukarıda belirtilen adımlar yalnızca varlığınız için çalışacaktır. Örneğin, başka bir varlık sınıfı eklemek veya mevcut varlık sınıfını kaldırmak için başarılı bir şekilde taşınacaktır. Ancak varlık sınıfınıza herhangi bir özellik ekler veya kaldırırsanız, bu bir istisna atar.

Step 10 - Özellik geçişini işlemek için, konfigürasyon sınıfı yapıcısında AutomaticMigrationDataLossAllowed = true ayarlamanız gerekir.

public Configuration() {
   AutomaticMigrationsEnabled = true;
   AutomaticMigrationDataLossAllowed = true;
   ContextKey = "EFCodeFirstDemo.MyContext";
}

Kod Tabanlı Geçiş

Yeni bir uygulama geliştirdiğinizde, veri modeliniz sık sık değişir ve model her değiştiğinde, veri tabanıyla senkronize olmaz. Entity Framework'ü, veri modelini her değiştirdiğinizde veritabanını otomatik olarak bırakacak ve yeniden oluşturacak şekilde yapılandırdınız. Kod tabanlı geçiş, geçiş üzerinde daha fazla kontrol sahibi olmak istediğinizde kullanışlıdır.

  • Varlık sınıfları eklediğinizde, kaldırdığınızda veya değiştirdiğinizde veya DbContext sınıfınızı değiştirdiğinizde, uygulamayı bir sonraki çalıştırışınızda, mevcut veritabanınızı otomatik olarak siler, modelle eşleşen yeni bir tane oluşturur ve onu test verileriyle tohumlandırır.

  • Code First Migrations özelliği, Code First'ün veritabanını bırakıp yeniden oluşturmak yerine veritabanı şemasını güncellemesini sağlayarak bu sorunu çözer. Uygulamayı dağıtmak için Taşıma İşlemlerini etkinleştirmeniz gerekir.

Veritabanındaki değişiklikleri taşımak için temel kural şu ​​şekildedir:

  • Taşımaları Etkinleştir
  • Taşıma Ekle
  • Veri tabanını güncelle

Aşağıdaki adım adım kod tabanı geçiş sürecine bir göz atalım.

Kod ilk yaklaşımını kullandığınızda, uygulamanız için bir veritabanınız olmaz.

Bu örnekte, aşağıdaki kodda gösterildiği gibi Öğrenci, Kurs ve Kayıt gibi 3 temel sınıfımızla yeniden başlayacağız.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Aşağıdaki bağlam sınıfıdır.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<
         MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 1 - Uygulamayı çalıştırmadan önce geçişi etkinleştirmeniz gerekir.

Step 2 - Araçlar → NuGet Paket Yöneticisi → Paket Yöneticisi Konsolundan Paket Yöneticisi Konsolunu açın.

Step 3 - Taşıma zaten etkin, şimdi aşağıdaki komutu çalıştırarak uygulamanıza geçiş ekleyin.

PM> add-migration "UniDB Schema"

Step 4 - Komut başarıyla yürütüldüğünde, aşağıdaki görüntüde gösterildiği gibi, komuta ilettiğiniz parametrenin adıyla bir zaman damgası öneki ile Taşıma klasöründe yeni bir dosyanın oluşturulduğunu göreceksiniz.

Step 5 - "Veri tabanını güncelle" komutunu kullanarak veri tabanını oluşturabilir veya güncelleyebilirsiniz.

PM> Update-Database -Verbose

"-Verbose" bayrağı, konsoldaki hedef veritabanına uygulanmakta olan SQL İfadelerini göstermeyi belirtir.

Step 6 - Öğrenci sınıfına bir tane daha 'Yaş' özelliği ekleyelim ve ardından güncelleme ifadesini çalıştıralım.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public int Age { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

PM → Update-Database –Verbose komutunu çalıştırdığınızda, komut başarıyla yürütüldüğünde veritabanınıza yeni sütun Age'in eklendiğini göreceksiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Bu bölümde, uygulamada birden fazla DbContext sınıfı olduğunda değişiklikleri veritabanına nasıl taşıyacağımızı öğreneceğiz.

  • Birden çok DbContext ilk olarak Entity Framework 6.0'da tanıtıldı.
  • Çoklu bağlam sınıfları tek bir veritabanına veya iki farklı veritabanına ait olabilir.

Örneğimizde, aynı veritabanı için iki Context sınıfı tanımlayacağız. Aşağıdaki kodda Öğrenci ve Öğretmen için iki DbContext sınıfı vardır.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
}

public class MyStudentContext : DbContext {
   public MyStudentContext() : base("UniContextDB") {}
   public virtual DbSet<Student> Students { get; set; }
}

public class Teacher {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime HireDate { get; set; }
}

public class MyTeacherContext : DbContext {
   public MyTeacherContext() : base("UniContextDB") {}
   public virtual DbSet<Teacher> Teachers { get; set; }
}

Yukarıdaki kodda da görebileceğiniz gibi "Öğrenci" ve "Öğretmen" olmak üzere iki model var. Her biri belirli bir ilgili bağlam sınıfıyla ilişkilidir, yani Öğrenci MyStudentContext ile ve Öğretmen MyTeacherContext ile ilişkilendirilir.

Aynı proje içinde birden fazla Bağlam sınıfı olduğunda, veritabanındaki değişiklikleri taşımak için temel kural aşağıda verilmiştir.

  • enable-migrations -ContextTypeName <DbContext-Name-with-Namespaces> MigrationsDirectory: <Migrations-Directory-Name>

  • Add-Migration -configuration <DbContext-Migrations-Configuration-Class-withNamespaces> <Migrations-Name>

  • Update-Database -configuration <DbContext-Migrations-Configuration-Class-withNamespaces> -Verbose

Paket Yöneticisi Konsolunda aşağıdaki komutu çalıştırarak MyStudentContext için geçişi etkinleştirelim.

PM→ enable-migrations -ContextTypeName:EFCodeFirstDemo.MyStudentContext

Çalıştırıldıktan sonra modeli geçiş geçmişine ekleyeceğiz ve bunun için aynı konsolda add-migration komutunu ateşlememiz gerekiyor.

PM→ add-migration -configuration EFCodeFirstDemo.Migrations.Configuration Initial

Şimdi veritabanındaki Öğrenciler ve Öğretmenler tablolarına bazı veriler ekleyelim.

static void Main(string[] args) {

   using (var context = new MyStudentContext()) {
	
      //// Create and save a new Students
      Console.WriteLine("Adding new students");

      var student = new Student {
         FirstMidName = "Alain", 
         LastName = "Bomer", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 24
      };

      context.Students.Add(student);

      var student1 = new Student {
         FirstMidName = "Mark",
         LastName = "Upston", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 30
      };

      context.Students.Add(student1);
      context.SaveChanges();
      // Display all Students from the database
      var students = (from s in context.Students orderby s.FirstMidName
         select s).ToList<Student>();
		
      Console.WriteLine("Retrieve all Students from the database:");

      foreach (var stdnt in students) {
         string name = stdnt.FirstMidName + " " + stdnt.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }

   using (var context = new MyTeacherContext()) {

      //// Create and save a new Teachers
      Console.WriteLine("Adding new teachers");

      var student = new Teacher {
         FirstMidName = "Alain", 
         LastName = "Bomer", 
         HireDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 24
      };

      context.Teachers.Add(student);

      var student1 = new Teacher {
         FirstMidName = "Mark", 
         LastName = "Upston", 
         HireDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 30
      };

      context.Teachers.Add(student1);
      context.SaveChanges();
  
      // Display all Teachers from the database
      var teachers = (from t in context.Teachers orderby t.FirstMidName
         select t).ToList<Teacher>();
		
      Console.WriteLine("Retrieve all teachers from the database:");

      foreach (var teacher in teachers) {
         string name = teacher.FirstMidName + " " + teacher.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", teacher.ID, name);
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }
}

Yukarıdaki kod çalıştırıldığında, aşağıdaki görüntüde gösterildiği gibi iki farklı model için iki farklı tablonun oluşturulduğunu göreceksiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.

Entity Framework 6'dan önce Entity Framework, diğer varlıklar veya karmaşık türler içinde yuvalanmış varlıkları veya karmaşık türleri tanımıyordu. Entity Framework modeli oluşturduğunda, yuvalanmış türler kayboldu.

Student, Course ve Enrollment adlı üç varlıklı temel modelimize sahip olduğumuz basit bir örneğe bakalım.

  • Kişi türü olan bir özellik Kimliği ekleyelim. Kişi başka bir varlıktır, Doğum Tarihi ve BabaAdı özelliklerini içerir.

  • Entity Framework terimlerinde, kimliği olmadığı ve bir varlığın parçası olduğu için, bir Entity Framework karmaşık türüdür ve Entity Framework'ün ilk sürümünden beri aslında karmaşık türler için destek aldık.

  • Kişi türü, aşağıdaki kodda gösterildiği gibi yuvalanmamıştır.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
   public Person Identity { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Person {

   public Person(string fatherName, DateTime birthDate) {
      FatherName = fatherName;
      BirthDate = birthDate;
   }
	
   public string FatherName { get; set; }
   public DateTime BirthDate { get; set; }
}

Entity Framework, önceki sürümlerde de kullanıldığında Kişi türlerinin nasıl kalıcı hale getirileceğini bilecektir.

Entity Framework Power Tool kullanarak Entity Framework'ün modeli nasıl yorumladığını göreceğiz. Program.cs dosyasına sağ tıklayın ve Entity Framework → View Entity Data Model (Salt okunur) öğesini seçin

Şimdi, Öğrenci sınıfında Kimlik özelliğinin tanımlandığını göreceksiniz.

Bu Person sınıfı başka bir varlık tarafından kullanılmayacaksa, onu Öğrenci sınıfının içine yerleştirebiliriz, ancak Entity Framework'ün bu önceki sürümü iç içe geçmiş türleri onaylamaz.

Eski sürümde, modeli yeniden oluşturursunuz, yalnızca tür tanınmaz, aynı zamanda orada olmadığı için özellik de yoktur, bu nedenle Entity Framework Person türünü hiç sürdürmez.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
	
   public DateTime EnrollmentDate { get; set; }
   public Person Identity { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

   public class Person {

      public Person(string fatherName, DateTime birthDate) {
         FatherName = fatherName;
         BirthDate = birthDate;
      }

      public string FatherName { get; set; }
      public DateTime BirthDate { get; set; }
   }
}

Entity Framework 6 ile, yuvalanmış varlıklar ve karmaşık türler tanınır. Yukarıdaki kodda, Kişinin Öğrenci sınıfının içine yerleştirildiğini görebilirsiniz.

Entity Framework'ün modeli bu sefer nasıl yorumladığını göstermek için Entity Framework Power Tool'u kullandığınızda, gerçek Identity özelliği ve Person karmaşık türü vardır. Böylece Entity Framework bu verileri sürdürecektir.

Artık Identity'nin Entity Framework 6'dan önce desteklenmeyen yuvalanmış bir varlık türü olduğunu görebilirsiniz.

Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.