Öğretici: ASP.NET MVC 5 uygulamasında EF ile Devralma Uygulama
Önceki öğreticide eşzamanlılık özel durumlarını işlediyseniz. Bu öğreticide veri modelinde devralmayı nasıl uygulayacağınız gösterilir.
Nesne odaklı programlamada, kodun yeniden kullanımını kolaylaştırmak için devralmayı kullanabilirsiniz. Bu öğreticide ve sınıflarını değiştirerek Instructor
hem eğitmenler hem de öğrenciler için ortak özellikler içeren LastName
bir Person
temel sınıftan türetilir.Student
Hiçbir web sayfası eklemez veya değiştirmezsiniz, ancak kodun bir bölümünü değiştirirsiniz ve bu değişiklikler otomatik olarak veritabanına yansıtılır.
Bu öğreticide şunları yaptınız:
- Devralmayı veritabanına eşlemeyi öğrenin
- Person sınıfını oluşturma
- Eğitmeni ve Öğrenciyi Güncelleştirme
- Modele Kişi Ekleme
- Geçişleri Oluşturma ve Güncelleştirme
- Uygulamayı test etme
- Azure’a dağıtın
Önkoşullar
Devralmayı veritabanına eşleme
Instructor
Veri modelindeki School
ve Student
sınıfları aynı olan çeşitli özelliklere sahiptir:
ve Student
varlıkları tarafından Instructor
paylaşılan özellikler için yedekli kodu ortadan kaldırmak istediğinizi varsayalım. Ya da adın bir eğitmenden mi yoksa öğrenciden mi geldiğiyle ilgilenmeden adları biçimlendirebilen bir hizmet yazmak istiyorsunuz. Yalnızca bu paylaşılan özellikleri içeren bir Person
temel sınıf oluşturabilir, ardından aşağıdaki çizimde gösterildiği gibi ve Student
varlıklarının bu temel sınıftan devralınır hale getirebilirsinizInstructor
:
Bu devralma yapısının veritabanında temsil edilebileceği çeşitli yollar vardır. Tek bir Person
tabloda hem öğrenciler hem de eğitmenler hakkında bilgi içeren bir tablonuz olabilir. Sütunların bazıları yalnızca eğitmenlere (HireDate
), bazıları yalnızca öğrencilere (EnrollmentDate
), bazıları her ikisine de (LastName
, FirstName
) uygulanabilir. Normalde, her satırın hangi türü temsil ettiğini belirten bir ayırıcı sütuna sahip olursunuz. Örneğin, ayrımcı sütunda eğitmenler için "Eğitmen" ve öğrenciler için "Öğrenci" olabilir.
Tek bir veritabanı tablosundan varlık devralma yapısı oluşturma deseni , hiyerarşi başına tablo (TPH) devralma olarak adlandırılır.
Alternatif olarak veritabanının devralma yapısına daha çok benzediğinden emin olabilirsiniz. Örneğin, tabloda yalnızca ad alanları ve tarih alanları Person
olan ayrı Instructor
ve Student
tablolarınız olabilir.
Her varlık sınıfı için veritabanı tablosu yapma deseni , tür başına tablo (TPT) devralma olarak adlandırılır.
Diğer bir seçenek de soyut olmayan tüm türleri tek tek tablolara eşlemektir. Devralınan özellikler de dahil olmak üzere bir sınıfın tüm özellikleri, ilgili tablonun sütunlarıyla eşler. Bu desen, Somut Sınıf Başına Tablo (TPC) devralma olarak adlandırılır. Daha önce gösterildiği gibi , Student
ve sınıfları için Person
TPC devralmayı uyguladıysanız, Student
devralma uygulandıktan sonra ve Instructor
tabloları öncekinden farklı Instructor
görünmeyecektir.
TPC ve TPH devralma desenleri genellikle Entity Framework'te TPT devralma desenlerine göre daha iyi performans sunar, çünkü TPT desenleri karmaşık birleştirme sorgularında sonuçlanabilir.
Bu öğreticide TPH devralmayı uygulama gösterilmektedir. TPH, Entity Framework'teki varsayılan devralma desenidir, bu nedenle tek yapmanız gereken bir Person
sınıf oluşturmak, ve Student
sınıflarını öğesinden Person
türetecek şekilde değiştirmekInstructor
, yeni sınıfı öğesine DbContext
eklemek ve bir geçiş oluşturmaktır. (Diğer devralma desenlerini uygulama hakkında bilgi için MSDN Entity Framework belgelerinde Tür Başına Tablo (TPT) Devralmayı Eşleme ve Somut Sınıf Başına Tablo (TPC) Devralmayı Eşleme bölümüne bakın.)
Person sınıfını oluşturma
Models klasöründe Person.cs dosyasını oluşturun ve şablon kodunu aşağıdaki kodla değiştirin:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public abstract class Person
{
public int ID { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "First name cannot be longer than 50 characters.")]
[Column("FirstName")]
[Display(Name = "First Name")]
public string FirstMidName { get; set; }
[Display(Name = "Full Name")]
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
}
}
Eğitmeni ve Öğrenciyi Güncelleştirme
Şimdi Person.sc değerleri devralmak için Instructor.cs ve Student.cs'yigüncelleştirin.
Instructor.cs dosyasında sınıfı sınıfından Instructor
Person
türetin ve anahtar ve ad alanlarını kaldırın. Kod aşağıdaki örneğe benzer olacaktır:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Instructor : Person
{
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Hire Date")]
public DateTime HireDate { get; set; }
public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; }
}
}
Student.cs dosyasında da benzer değişiklikler yapın. Student
sınıfı aşağıdaki örneğe benzer olacaktır:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Student : Person
{
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Enrollment Date")]
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
Modele Kişi Ekleme
SchoolContext.cs içinde varlık türü için Person
bir DbSet
özellik ekleyin:
public DbSet<Person> People { get; set; }
Entity Framework'ün hiyerarşi başına tablo devralmayı yapılandırmak için ihtiyaç duyduğu tek şey budur. Gördüğünüz gibi veritabanı güncelleştirildiğinde ve Instructor
tablolarının Student
yerine bir Person
tablo olur.
Geçişleri Oluşturma ve Güncelleştirme
Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu girin:
Add-Migration Inheritance
Update-Database
PMC'de komutunu çalıştırın. Geçişlerin nasıl işlendiğini bilmediği mevcut verilerimiz olduğundan komut bu noktada başarısız olur. Aşağıdakine benzer bir hata iletisi alırsınız:
'dbo nesnesi bırakılamadı. Yabancı ANAHTAR kısıtlaması tarafından başvurulacağından eğitmenin.
Open Migrations< timestamp>_Inheritance.cs ve yöntemini aşağıdaki kodla değiştirinUp
:
public override void Up()
{
// Drop foreign keys and indexes that point to tables we're going to drop.
DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student");
DropIndex("dbo.Enrollment", new[] { "StudentID" });
RenameTable(name: "dbo.Instructor", newName: "Person");
AddColumn("dbo.Person", "EnrollmentDate", c => c.DateTime());
AddColumn("dbo.Person", "Discriminator", c => c.String(nullable: false, maxLength: 128, defaultValue: "Instructor"));
AlterColumn("dbo.Person", "HireDate", c => c.DateTime());
AddColumn("dbo.Person", "OldId", c => c.Int(nullable: true));
// Copy existing Student data into new Person table.
Sql("INSERT INTO dbo.Person (LastName, FirstName, HireDate, EnrollmentDate, Discriminator, OldId) SELECT LastName, FirstName, null AS HireDate, EnrollmentDate, 'Student' AS Discriminator, ID AS OldId FROM dbo.Student");
// Fix up existing relationships to match new PK's.
Sql("UPDATE dbo.Enrollment SET StudentId = (SELECT ID FROM dbo.Person WHERE OldId = Enrollment.StudentId AND Discriminator = 'Student')");
// Remove temporary key
DropColumn("dbo.Person", "OldId");
DropTable("dbo.Student");
// Re-create foreign keys and indexes pointing to new table.
AddForeignKey("dbo.Enrollment", "StudentID", "dbo.Person", "ID", cascadeDelete: true);
CreateIndex("dbo.Enrollment", "StudentID");
}
Bu kod aşağıdaki veritabanı güncelleştirme görevlerini üstlenir:
Student tablosuna işaret eden yabancı anahtar kısıtlamalarını ve dizinlerini kaldırır.
Eğitmen tablosunu Kişi olarak yeniden adlandırır ve Öğrenci verilerini depolamak için gerekli değişiklikleri yapar:
- Öğrenciler için null atanabilir EnrollmentDate ekler.
- Bir satırın öğrenciye mi yoksa eğitmene mi yönelik olduğunu belirtmek için Ayrımcı sütunu ekler.
- Öğrenci satırlarının işe alma tarihleri olmayacağından HireDate değerini null yapılabilir hale getirir.
- Öğrencilere işaret eden yabancı anahtarları güncelleştirmek için kullanılacak geçici bir alan ekler. Öğrencileri Kişi tablosuna kopyaladığınızda, yeni birincil anahtar değerleri elde ederler.
Öğrenci tablosundaki verileri Kişi tablosuna kopyalar. Bu, öğrencilere yeni birincil anahtar değerleri atanmalarına neden olur.
Öğrencilere işaret eden yabancı anahtar değerlerini düzeltir.
Yabancı anahtar kısıtlamalarını ve dizinlerini yeniden oluşturarak bunları Kişi tablosuna yönlendirir.
(Birincil anahtar türü olarak tamsayı yerine GUID kullandıysanız, öğrencinin birincil anahtar değerlerinin değişmesi gerekmez ve bu adımlardan bazıları atlanabilirdi.)
update-database
komutunu yeniden çalıştırın.
(Bir üretim sisteminde, önceki veritabanı sürümüne geri dönmek için bunu kullanmanız gerekme ihtimaline karşı Down yönteminde ilgili değişiklikleri yaparsınız. Bu öğreticide Down yöntemini kullanmayacaksınız.)
Not
Verileri geçirirken ve şema değişiklikleri yaparken başka hatalar almak mümkündür. Çözemediğiniz geçiş hataları alırsanız, Web.config dosyasındaki bağlantı dizesi değiştirerek veya veritabanını silerek öğreticiye devam edebilirsiniz. En basit yaklaşım, veritabanınıWeb.config dosyasında yeniden adlandırmaktır. Örneğin, aşağıdaki örnekte gösterildiği gibi veritabanı adını ContosoUniversity2 olarak değiştirin:
<add name="SchoolContext"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity2;Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
Yeni bir veritabanıyla geçirecek veri yoktur ve komutun update-database
hatasız tamamlanma olasılığı çok daha yüksektir. Veritabanını silme yönergeleri için bkz. Visual Studio 2012'den Veritabanı Bırakma. Öğreticiye devam etmek için bu yaklaşımı benimserseniz, bu öğreticinin sonundaki dağıtım adımını atlayın veya yeni bir siteye ve veritabanına dağıtın. Bir güncelleştirmeyi zaten dağıtmakta olduğunuz siteye dağıtırsanız EF, geçişleri otomatik olarak çalıştırdığında aynı hatayı orada alır. Geçiş hatasını gidermek istiyorsanız, en iyi kaynak Entity Framework forumlarından veya StackOverflow.com biridir.
Uygulamayı test etme
Siteyi çalıştırın ve çeşitli sayfaları deneyin. Her şey daha önce olduğu gibi çalışır.
Sunucu Gezgini'ndeVeri Bağlantıları\SchoolContext ve ardından Tablolar'ı genişletin; Öğrenci ve Eğitmen tablolarının bir Kişi tablosuyla değiştirildiğini görürsünüz. Kişi tablosunu genişletirseniz, öğrenci ve eğitmen tablolarında kullanılan tüm sütunların bulunduğunu görürsünüz.
Kişi tablosuna sağ tıklayın ve sonra ayrımcı sütunu görmek için Tablo Verilerini Göster'e tıklayın.
Aşağıdaki diyagramda yeni School veritabanının yapısı gösterilmektedir:
Azure’a dağıtın
Bu bölüm, bu öğretici serisinin 3. Bölüm, Sıralama, Filtreleme ve Sayfalama bölümündeki isteğe bağlı Uygulamayı Azure'a dağıtma bölümünü tamamlamanızı gerektirir. Yerel projenizdeki veritabanını silerek çözdüğünüz geçiş hataları varsa bu adımı atlayın; veya yeni bir site ve veritabanı oluşturun ve yeni ortama dağıtın.
Visual Studio'da, Çözüm Gezgini'da projeye sağ tıklayın ve bağlam menüsünden Yayımla'yı seçin.
Yayımla’ya tıklayın.
Web uygulaması varsayılan tarayıcınızda açılır.
Çalıştığını doğrulamak için uygulamayı test edin.
Veritabanına erişen bir sayfayı ilk kez çalıştırdığınızda, Entity Framework veritabanını geçerli veri modeliyle güncel yapmak için gereken tüm geçiş
Up
yöntemlerini çalıştırır.
Kodu alma
Ek kaynaklar
Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi - Önerilen Kaynaklar bölümünde bulunabilir.
Bu ve diğer devralma yapıları hakkında daha fazla bilgi için bkz. MSDN'de TPT Devralma Düzeni ve TPH Devralma Düzeni . Sonraki öğreticide, görece gelişmiş çeşitli Entity Framework senaryolarını işlemeyi öğreneceksiniz.
Sonraki adımlar
Bu öğreticide şunları yaptınız:
- Devralmayı veritabanına eşlemeyi öğrendin
- Person sınıfı oluşturuldu
- Güncelleştirilmiş Eğitmen ve Öğrenci
- Modele Kişi Eklendi
- Oluşturulan ve Güncelleştirilen Geçişler
- Uygulamayı test etti
- Azure'a dağıtıldı
Entity Framework Code First kullanan ASP.NET web uygulamaları geliştirmenin temellerini aştığınızda dikkat etmeniz gereken konular hakkında bilgi edinmek için sonraki makaleye ilerleyin.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin