öğretici: EF Core ile karmaşık veri modeli ASP.NET MVC oluşturma

Önceki öğreticilerde, üç varlıktan oluşan basit bir veri modeliyle çalıştık. Bu öğreticide, daha fazla varlık ve ilişki ekleyeceksiniz ve biçimlendirme, doğrulama ve veritabanı eşleme kurallarını belirterek veri modelini özelleştireceksiniz.

İşiniz bittiğinde, varlık sınıfları aşağıdaki çizimde gösterilen tamamlanmış veri modelini oluşturacak:

Varlık diyagramı

Bu öğreticide şunları yaptınız:

  • Veri modelini özelleştirme
  • Öğrenci varlığında değişiklik yap
  • Eğitmen varlığı oluşturma
  • OfficeAssignment varlığı oluştur
  • Kurs varlığını değiştirme
  • Departman varlığı oluştur
  • Kayıt varlığını değiştirme
  • Veritabanı bağlamını güncelleştirme
  • Test verileriyle çekirdek veritabanı
  • Geçiş ekleme
  • Bağlantı dizesini değiştirme
  • Veritabanını güncelleştirme

Önkoşullar

Veri modelini özelleştirme

Bu bölümde, biçimlendirme, doğrulama ve veritabanı eşleme kurallarını belirten öznitelikleri kullanarak veri modelini nasıl özelleştireceğinizi göreceksiniz. Ardından, aşağıdaki bölümlerde, zaten oluşturduğunuz sınıflara öznitelikler ekleyerek ve modeldeki kalan varlık türleri için yeni sınıflar oluşturarak tüm okul veri modelini oluşturacaksınız.

DataType özniteliği

Öğrenci kayıt tarihleri için tüm Web sayfaları Şu anda tarihle birlikte görüntülenir, ancak bu alan için tüm önemli bir tarih olması gerekir. Veri ek açıklaması özniteliklerini kullanarak, verileri gösteren her görünümde görüntü biçimini giderecek bir kod değişikliği yapabilirsiniz. Bunun nasıl yapılacağını gösteren bir örnek görmek için, sınıfındaki özelliğine bir özniteliği ekleyeceksiniz EnrollmentDate Student .

Modeller/öğrenci. cs' de, using ad alanı için bir ifade ekleyin System.ComponentModel.DataAnnotations ve DataType DisplayFormat EnrollmentDate Aşağıdaki örnekte gösterildiği gibi özelliğe ve özniteliklerini ekleyin:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime EnrollmentDate { get; set; }

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

DataTypeÖzniteliği, veritabanı iç türünden daha belirgin bir veri türü belirtmek için kullanılır. Bu durumda, tarihi ve saati değil yalnızca tarihi izlemek istiyoruz. DataTypeSabit listesi, tarih, saat, PhoneNumber, para birimi, Emaadresi gibi birçok veri türünü sağlar. DataTypeÖzniteliği Ayrıca uygulamanın türe özgü özellikleri otomatik olarak sağlamasını da sağlayabilir. Örneğin, için bir mailto: bağlantı oluşturulabilir DataType.EmailAddress ve HTML5 'i destekleyen tarayıcılarda için bir tarih seçici sağlaneklenebilir DataType.Date . DataTypeÖZNITELIĞI data- HTML 5 tarayıcılarının ANLAYABILMESI için HTML 5 (bir veri Dash) öznitelikleri yayar. DataTypeÖznitelikler hiçbir doğrulama sağlamaz.

DataType.Date görüntülenen tarihin biçimini belirtmez. Varsayılan olarak, veri alanı sunucunun CultureInfo öğesine göre varsayılan biçimlere göre görüntülenir.

DisplayFormatÖznitelik, tarih biçimini açıkça belirtmek için kullanılır:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

ApplyFormatInEditModeAyar, bir metin kutusunda değer görüntülenmek üzere görüntülendiğinde biçimlendirmenin de uygulanacağını belirtir. (Bazı alanlar için bunu istemiyor olabilirsiniz; örneğin, para birimi değerleri için metin kutusundaki para birimi sembolünü düzenlemenin değiştirilmesini istemeyebilirsiniz.)

DisplayFormatÖzniteliğini kendisi kullanabilirsiniz, ancak özniteliği de kullanmak iyi bir fikir olabilir DataType . DataTypeÖzniteliği, bir ekranda nasıl işlenirim aksine, verilerin semantiğini sunar ve aşağıdaki avantajları sağlar DisplayFormat :

  • Tarayıcı HTML5 özelliklerini etkinleştirebilir (örneğin, bir Takvim denetimini, yerel ayara uygun para birimi sembolünü, e-posta bağlantılarını, bazı istemci tarafı giriş doğrulamasını vb. göstermek için).

  • Varsayılan olarak tarayıcı, verileri yerel ayarınızı temel alarak doğru biçimi kullanarak işleyebilir.

Daha fazla bilgi için bkz. <input> etiket Yardımcısı belgeleri.

Uygulamayı çalıştırın, öğrenciler dizin sayfasına gidin ve kayıt tarihleri için saatlerin artık gösterilmediğine dikkat edin. Aynı değer öğrenci modelini kullanan herhangi bir görünüm için de geçerli olacaktır.

Öğrenciler Dizin sayfası tarihleri zamansız gösterme

StringLength özniteliği

Ayrıca, öznitelikleri kullanarak veri doğrulama kuralları ve doğrulama hata iletileri de belirtebilirsiniz. StringLengthöznitelik, veritabanında en fazla uzunluğu ayarlar ve ASP.NET Core MVC için istemci tarafı ve sunucu tarafı doğrulaması sağlar. Bu öznitelikte en küçük dize uzunluğunu da belirtebilirsiniz, ancak en küçük değerin veritabanı şemasında hiçbir etkisi yoktur.

Kullanıcıların bir ad için 50 ' den fazla karakter girmemesini istediğinizi varsayalım. Bu kısıtlamayı eklemek için StringLength LastName FirstMidName Aşağıdaki örnekte gösterildiği gibi öznitelikleri ve özelliklerine ekleyin:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        [StringLength(50)]
        public string LastName { get; set; }
        [StringLength(50)]
        public string FirstMidName { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime EnrollmentDate { get; set; }

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

Öznitelik, bir StringLength kullanıcının ad için boşluk girmesini engellemez. RegularExpressionGirişe kısıtlama uygulamak için özniteliğini kullanabilirsiniz. Örneğin, aşağıdaki kod ilk karakterin büyük küçük harf olmasını ve geri kalan karakterlerin alfabetik olmasını gerektirir:

[RegularExpression(@"^[A-Z]+[a-zA-Z]*$")]

MaxLengthÖznitelik, StringLength özniteliğe benzer ancak istemci tarafı doğrulaması sağlamayan işlevselliği sağlar.

Veritabanı modeli, veritabanı şemasında değişiklik yapılmasını gerektiren bir şekilde değiştirildi. Uygulama kullanıcı arabirimini kullanarak, veritabanına eklemiş olduğunuz herhangi bir veriyi kaybetmeden Şemayı güncelleştirmek için geçişleri kullanacaksınız.

Değişikliklerinizi kaydedin ve projeyi derleyin. Ardından proje klasöründe komut penceresini açın ve aşağıdaki komutları girin:

dotnet ef migrations add MaxLengthOnNames
dotnet ef database update

migrations addBu komut, iki sütun için en fazla uzunluğu daha kısa hale yaptığından, veri kaybının gerçekleşebileceğini uyarır. Geçişler <timeStamp> _MaxLengthOnNames. cs adlı bir dosya oluşturur. Bu dosya, Up geçerli veri modeliyle eşleşecek şekilde veritabanını güncelleştirecek yöntemdeki kodu içerir. database updateKomut bu kodu çalıştırdı.

Geçiş dosyası adının ön eki olan zaman damgası, geçişleri sıralamak için Entity Framework tarafından kullanılır. Update-database komutunu çalıştırmadan önce birden çok geçiş oluşturabilirsiniz ve sonra tüm geçişler oluşturuldukları sırada uygulanır.

Uygulamayı çalıştırın, öğrenciler sekmesini seçin, Yeni oluştur' a tıklayın ve 50 karakterden daha uzun bir ad girmeyi deneyin. Uygulamanın bunu yapmasını önleyebilmelidir.

Column özniteliği

Ayrıca, sınıflarınızın ve özelliklerinin veritabanına nasıl eşlenildiğini denetlemek için özniteliklerini de kullanabilirsiniz. FirstMidNameAlan aynı zamanda bir orta ad içerebileceğinden, birinci ad alanı için adı kullandığınızı varsayalım. Ancak veritabanına FirstName karşı geçici sorgular yazmayacak olan kullanıcılar bu ada alışkın olduğundan, veritabanı sütununun adlandırılmak istiyorsunuz. Bu eşlemeyi yapmak için Column özniteliğini kullanabilirsiniz.

ColumnÖzniteliği veritabanı oluşturulduğunda, Student özelliği ile eşlenen tablonun sütununun FirstMidName adlandırılacağını belirtir FirstName . Diğer bir deyişle, kodunuz öğesine başvurduğunda Student.FirstMidName , veriler tablonun sütununda gelir veya güncelleştirilir FirstName Student . Sütun adları belirtmezseniz, bunlar Özellik adı ile aynı ada verilir.

Öğrenci. cs dosyasında, için bir ifade ekleyin using System.ComponentModel.DataAnnotations.Schema ve FirstMidName aşağıdaki vurgulanmış kodda gösterildiği gibi, özelliğine sütun adı özniteliği ekleyin:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        [StringLength(50)]
        public string LastName { get; set; }
        [StringLength(50)]
        [Column("FirstName")]
        public string FirstMidName { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime EnrollmentDate { get; set; }

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

Özniteliği ekleme modeli, Column SchoolContext tarafından yedeklendiğinden, veritabanıyla eşleşmeyecek şekilde değişir.

Değişikliklerinizi kaydedin ve projeyi derleyin. Ardından proje klasöründe komut penceresini açın ve başka bir geçiş oluşturmak için aşağıdaki komutları girin:

dotnet ef migrations add ColumnFirstName
dotnet ef database update

SQL Server Nesne Gezgini, öğrenci tablosu tasarımcısı ' nı öğrenci tablosu ' na çift tıklayarak açın.

Geçişlerde SSOX 'teki öğrenciler tablosu

İlk iki geçişi uygulamadan önce ad sütunları nvarchar (MAX) türünde. Artık nvarchar (50) ve sütun adı FirstMidName iken FirstName olarak değiştirilmiştir.

Not

Aşağıdaki bölümlerde tüm varlık sınıflarını oluşturmayı bitirmeden önce derlemeyi denerseniz Derleyici hataları alabilirsiniz.

Öğrenci varlığındaki değişiklikler

Öğrenci varlığı

Modeller/öğrenci. cs' de, daha önce eklediğiniz kodu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        [Required]
        [StringLength(50)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
        [Required]
        [StringLength(50)]
        [Column("FirstName")]
        [Display(Name = "First Name")]
        public string FirstMidName { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Enrollment Date")]
        public DateTime EnrollmentDate { get; set; }
        [Display(Name = "Full Name")]
        public string FullName
        {
            get
            {
                return LastName + ", " + FirstMidName;
            }
        }

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

Gerekli öznitelik

RequiredÖzniteliği, ad özellikleri gerekli alanları yapar. RequiredDeğer türleri (DateTime, int, Double, float, vb.) gibi null yapılamayan türler için öznitelik gerekli değildir. Null olmayan türler otomatik olarak gerekli alanlar olarak değerlendirilir.

RequiredÖzniteliğinin zorlanmak üzere ile birlikte kullanılması gerekir MinimumLength MinimumLength .

[Display(Name = "Last Name")]
[Required]
[StringLength(50, MinimumLength=2)]
public string LastName { get; set; }

Display özniteliği

DisplayÖznitelik, metin kutularının açıklamalı alt yazısının her örnekteki Özellik adı yerine "ilk ad", "soyadı", "tam ad" ve "kayıt tarihi" olması gerektiğini belirtir (kelimeleri hiçbir alan içermez).

FullName hesaplanan özelliği

FullName , diğer iki özelliği bir arada kullanarak oluşturulan bir değeri döndüren hesaplanan bir özelliktir. Bu nedenle yalnızca bir get erişimcisi FullName vardır ve veritabanında sütun oluşturulmaz.

Eğitmen varlığı oluşturma

Eğitmen varlığı

Models/Instructor.cs oluşturun ve şablon kodunu aşağıdaki kodla değiştirerek:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Instructor
    {
        public int ID { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        [StringLength(50)]
        public string LastName { get; set; }

        [Required]
        [Column("FirstName")]
        [Display(Name = "First Name")]
        [StringLength(50)]
        public string FirstMidName { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Hire Date")]
        public DateTime HireDate { get; set; }

        [Display(Name = "Full Name")]
        public string FullName
        {
            get { return LastName + ", " + FirstMidName; }
        }

        public ICollection<CourseAssignment> CourseAssignments { get; set; }
        public OfficeAssignment OfficeAssignment { get; set; }
    }
}

Öğrenci ve Eğitmen varlıklarında çeşitli özelliklerin aynı olduğunu fark vardır. Bu serinin devamlarında devralmayı uygulama öğreticisinde, yedekliliği ortadan kaldırmak için bu kodu yeniden düzenlemeye devam edin.

Bir satıra birden çok öznitelik koyabilirsiniz, bu nedenle öznitelikleri aşağıdaki HireDate gibi de yazabilirsiniz:

[DataType(DataType.Date),Display(Name = "Hire Date"),DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

CourseAssignments ve OfficeAssignment gezinti özellikleri

ve CourseAssignments özellikleri OfficeAssignment gezinti özellikleridir.

Eğitmen herhangi bir sayıda kurs öğretebilir, bu CourseAssignments nedenle bir koleksiyon olarak tanımlanır.

public ICollection<CourseAssignment> CourseAssignments { get; set; }

Bir gezinti özelliği birden çok varlığı tutabilirse, türü girdilerin eklenemedi, silinebilir ve güncelleştirilebilir bir liste olması gerekir. veya veya ICollection<T> gibi bir tür List<T> HashSet<T> belirterek. belirtirsanız ICollection<T> EF varsayılan olarak HashSet<T> bir koleksiyon oluşturur.

Bu varlıkların neden CourseAssignment varlık olduğunu, çoka çok ilişkileriyle ilgili bölümünde aşağıda açıklanmıştır.

Contoso University iş kuralları, bir eğitmenin en fazla bir ofisi olduğunu, bu nedenle özelliğin tek bir OfficeAssignment varlığı olduğunu (herhangi bir ofis atanmamışsa OfficeAssignment null olabilir) ifade eder.

public OfficeAssignment OfficeAssignment { get; set; }

OfficeAssignment varlığı oluşturma

OfficeAssignment varlığı

Models/OfficeAssignment.cs'yi aşağıdaki kodla oluşturun:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class OfficeAssignment
    {
        [Key]
        public int InstructorID { get; set; }
        [StringLength(50)]
        [Display(Name = "Office Location")]
        public string Location { get; set; }

        public Instructor Instructor { get; set; }
    }
}

Anahtar özniteliği

ile varlıklar arasında bire sıfır veya bir Instructor ilişkisi OfficeAssignment vardır. Bir ofis ataması yalnızca atandığı eğitmenle ilişkili olarak mevcuttur ve bu nedenle birincil anahtarı da varlığa yabancı Instructor anahtarıdır. Ancak Entity Framework adı veya adlandırma kuralına uymaz, çünkü bu varlığın birincil anahtarı olarak InstructorID otomatik ID olarak classnameID tanıyamıyorum. Bu Key nedenle, özniteliği anahtar olarak tanımlamak için kullanılır:

[Key]
public int InstructorID { get; set; }

Ayrıca, varlığın kendi birincil anahtarı varsa ancak özelliği classnameID veya ID dışında bir Key adla adlandırabilirsiniz.

Varsayılan olarak, sütun tanımlayıcı bir ilişki için olduğundan EF anahtarı veritabanı tarafından oluşturulmadı olarak kabul ediyor.

Eğitmen gezinti özelliği

Eğitmen varlığının boş değerdilebilir bir gezinti özelliği vardır (bir eğitmenin bir ofis ataması olmayabilir), OfficeAssignment varlığı da null değerdilemez bir gezinti özelliğine (bir ofis ataması eğitmen olmadan mevcut olamaysa da, null değere sahip OfficeAssignment Instructor InstructorID değildir) vardır. Eğitmen varlığında ilgili bir OfficeAssignment varlığı olduğunda, her varlığın gezinti özelliğinde diğer varlığa bir başvurusu olur.

İlgili eğitmenin olması gerektiğini belirtmek için Eğitmen gezinti özelliğine bir öznitelik koyabilirsiniz, ancak yabancı anahtar (bu tablonun anahtarı da bu anahtardır) null değer atılamaz olduğundan bunu yapmak zorunda [Required] InstructorID değildir.

Kurs varlığını değiştirme

Kurs varlığı

Models/Course.cs içinde, daha önce ekley kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Name = "Number")]
        public int CourseID { get; set; }

        [StringLength(50, MinimumLength = 3)]
        public string Title { get; set; }

        [Range(0, 5)]
        public int Credits { get; set; }

        public int DepartmentID { get; set; }

        public Department Department { get; set; }
        public ICollection<Enrollment> Enrollments { get; set; }
        public ICollection<CourseAssignment> CourseAssignments { get; set; }
    }
}

Kurs varlığı, ilgili Departman varlığını ve bir gezinti özelliğine sahip DepartmentID olan yabancı anahtar Department özelliğine sahip.

Bu Entity Framework ilgili varlık için bir gezinti özelliğine sahipken veri modelinize yabancı anahtar özelliği eklemenizi gerektirmez. EF, gerektiğinde veritabanında otomatik olarak yabancı anahtarlar oluşturur ve bunlar için gölge özellikler oluşturur. Ancak veri modelinde yabancı anahtarın olması güncelleştirmeleri daha basit ve daha verimli hale getirir. Örneğin, düzenlemek için bir varlık getirirken, yükleyemiyorsanız varlık null olur, dolayısıyla varlığı güncelleştirin, önce varlığı Course Department Course getirmeniz Department gerekir. Yabancı anahtar özelliği DepartmentID veri modeline ekli olduğunda, güncelleştirmeden önce varlığı Department getirmeniz gerek değildir.

DatabaseGenerated özniteliği

özelliğinde parametresine sahip özniteliği, birincil anahtar değerlerinin veritabanı tarafından DatabaseGenerated None CourseID oluşturulmak yerine kullanıcı tarafından sağlanıyor olduğunu belirtir.

[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Number")]
public int CourseID { get; set; }

Varsayılan olarak, Entity Framework birincil anahtar değerlerinin veritabanı tarafından oluşturulanı varsayıyor. Çoğu senaryoda bunu istediğiniz gibidir. Ancak varlıklar için, bir departman için 1000 serisi, başka bir departman için 2000 serisi gibi kullanıcı tarafından belirtilen kurs numarasını Course kullanırsınız.

Özniteliği, bir satırın oluşturulma veya güncelleştirme tarihini kaydetmek için kullanılan veritabanı sütunlarında olduğu gibi varsayılan DatabaseGenerated değerleri oluşturmak için de kullanılabilir. Daha fazla bilgi için bkz. Oluşturulan Özellikler.

Yabancı anahtar ve gezinti özellikleri

Varlıkta yabancı anahtar özellikleri ve gezinti Course özellikleri aşağıdaki ilişkileri yansıtıyor:

Kurs bir bölüme atandığı için yukarıda belirtilen nedenlerle yabancı anahtar DepartmentID Department ve gezinti özelliği vardır.

public int DepartmentID { get; set; }
public Department Department { get; set; }

Bir kursta herhangi bir sayıda öğrenci kayıtlı olabilir, bu nedenle Enrollments gezinti özelliği bir koleksiyondur:

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

Bir kurs birden çok eğitmen tarafından öğretilir, bu nedenle gezinti özelliği bir CourseAssignments koleksiyondur (tür daha CourseAssignment sonra açıklanmıştır):

public ICollection<CourseAssignment> CourseAssignments { get; set; }

Departman varlığı oluşturma

Departman varlığı

Models/Department.cs'yi aşağıdaki kodla oluşturun:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Department
    {
        public int DepartmentID { get; set; }

        [StringLength(50, MinimumLength = 3)]
        public string Name { get; set; }

        [DataType(DataType.Currency)]
        [Column(TypeName = "money")]
        public decimal Budget { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Start Date")]
        public DateTime StartDate { get; set; }

        public int? InstructorID { get; set; }

        public Instructor Administrator { get; set; }
        public ICollection<Course> Courses { get; set; }
    }
}

Column özniteliği

Daha önce sütun adı Column eşlemesini değiştirmek için özniteliğini kullandın. Varlığın kodunda özniteliği, veritabanındaki SQL türü kullanılarak sütunun tanımlandığı şekilde veri türü eşlemesini Department Column SQL Server money kullanılır:

[Column(TypeName="money")]
public decimal Budget { get; set; }

Sütun eşlemesi genellikle gerekli değildir çünkü Entity Framework için tanımladığınız CLR türüne SQL Server uygun veri türünü seçer. CLR decimal türü, bir SQL Server decimal eşler. Ancak bu durumda sütunun para birimi tutarlarını tut olacağını ve para veri türünün bunun için daha uygun olduğunu biliyorsunuz.

Yabancı anahtar ve gezinti özellikleri

Yabancı anahtar ve gezinti özellikleri aşağıdaki ilişkileri gösterir:

Bir departmanın yöneticisi olabilir veya olabilir ve yönetici her zaman eğitmendir. Bu nedenle özelliği, Eğitmen varlığının yabancı anahtarı olarak dahil edilir ve özelliği null değer olarak işaretlemek için tür ataması sonrasında bir InstructorID int soru işareti eklenir. Gezinti özelliği olarak adlandırılmıştır Administrator ancak Bir Eğitmen varlığı içerir:

public int? InstructorID { get; set; }
public Instructor Administrator { get; set; }

Bir departmanda çok sayıda kurs olabilir, bu nedenle Courses gezinti özelliği vardır:

public ICollection<Course> Courses { get; set; }

Not

Kural gereği, Entity Framework null değer verilemez yabancı anahtarlar ve çoka çok ilişkiler için basamaklı silmeyi sağlar. Bu durum döngüsel basamaklı silme kurallarına yol açarak geçiş eklemeye çalışma sırasında bir özel durumla sonuçlanabilecektir. Örneğin, özelliği null değere değiştirilebilir olarak tanımlamadıysanız EF, eğitmeni silişte bölümü silmek için basamaklı silme kuralı yapılandırabilir ve bu sizin olmasını istediğiniz Department.InstructorID şey değildir. İş kurallarınız özelliğinin null değere sahip olmayan bir değere sahip olması için ilişkide basamaklı silmeyi devre dışı bırakmak için aşağıdaki InstructorID fluent API deyimini kullansanız iyi olur:

modelBuilder.Entity<Department>()
   .HasOne(d => d.Administrator)
   .WithMany()
   .OnDelete(DeleteBehavior.Restrict)

Kayıt varlığını değiştirme

Kayıt varlığı

Models/Enrollment.cs içinde, daha önce ekley kodunu aşağıdaki kodla değiştirin:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    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; }
        [DisplayFormat(NullDisplayText = "No grade")]
        public Grade? Grade { get; set; }

        public Course Course { get; set; }
        public Student Student { get; set; }
    }
}

Yabancı anahtar ve gezinti özellikleri

Yabancı anahtar özellikleri ve gezinti özellikleri aşağıdaki ilişkileri gösterir:

Kayıt kaydı tek bir kursa ait olduğu için yabancı anahtar CourseID özelliği ve gezinti özelliği Course vardır:

public int CourseID { get; set; }
public Course Course { get; set; }

Kayıt kaydı tek bir öğrenciye ait olduğu için yabancı anahtar StudentID özelliği ve gezinti özelliği Student vardır:

public int StudentID { get; set; }
public Student Student { get; set; }

Çoka Çok ilişkileri

ve varlıkları arasında çoka çok ilişkisi vardır ve varlık, veritabanında yüke sahip çoka çok birleştirme Student tablosu olarak Course işlev Enrollment gösterir. "Yük ile", tablonun bir araya gelen tablolar için yabancı anahtarların yanı sıra ek veriler (bu durumda birincil anahtar ve Enrollment özellik) içerdiği anlamına Grade gelir.

Aşağıdaki çizimde bu ilişkilerin bir varlık diyagramında nasıl olduğu gösterilmiştir. (Bu diyagram EF 6.x için Entity Framework Power Tools kullanılarak oluşturulmuş; diyagramı oluşturmak öğreticinin bir parçası değil, yalnızca burada çizim olarak kullanılıyor.)

Student-Course çok ilişkisi

Her ilişki çizgisinin bir ucunda 1, diğer ucunda da bire çok ilişkisini gösteren yıldız (*) vardır.

Tabloda Enrollment not bilgileri yoksa yalnızca iki yabancı anahtar ve içermesi CourseID StudentID gerekir. Bu durumda, veritabanında yük (veya saf birleştirme tablosu) olmadan çoka çok birleştirme tablosu olabilir. ve varlıkları bu tür çoka çok ilişkisine sahiptir ve sonraki adımınız yük olmadan birleştirme tablosu olarak işlev yapmak için bir Instructor Course varlık sınıfı oluşturmaktır.

EF Core çoka çok ilişkiler için örtülü birleştirme tablolarını destekler, ancak bu açık birleşim tablosu kullanmak için güncelleştirilmedi. Güncelleştirilmiş bu öğreticinin Sayfalarsürümü olan Çoka Razor Çok İlişkiler'e bakın.

CourseAssignment varlığı

CourseAssignment varlığı

Models/CourseAssignment.cs'yi aşağıdaki kodla oluşturun:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class CourseAssignment
    {
        public int InstructorID { get; set; }
        public int CourseID { get; set; }
        public Instructor Instructor { get; set; }
        public Course Course { get; set; }
    }
}

Varlık adlarını birleştirme

Eğitmen-Kurslar çoka çok ilişkisi için veritabanında bir birleştirme tablosu gereklidir ve bir varlık kümesiyle temsil etmek gerekir. Bir birleşim varlığının adı yaygındır EntityName1EntityName2 ve bu durumda CourseInstructor olur. Ancak ilişkiyi açıklayan bir ad seçmenizi öneririz. Veri modelleri basit bir şekilde başlar ve daha sonra yük alma yükü olmayan birleştirmelerle büyür. Açıklayıcı bir varlık adıyla başlarsanız, adı daha sonra değiştirmek zorunda olmayacaksınız. İdeal olarak, birleştirme varlığının iş etki alanında kendi doğal (muhtemelen tek sözcük) adı olur. Örneğin, Kitaplar ve Müşteriler Derecelendirmeler aracılığıyla bağlanıyor olabilir. Bu ilişki için, CourseAssignment yerine daha iyi bir seçenektir. CourseInstructor

Bileşik anahtar

Yabancı anahtarlar null değere konulamaz ve tablonun her bir satırı benzersiz olarak tanımlanmaz. Ayrı bir birincil anahtara gerek yoktur. ve InstructorID özellikleri bileşik birincil anahtar olarak CourseID çalışmalı. EF'ye bileşik birincil anahtarları tanımlamanın tek yolu fluent API'sini kullanmaktır (öznitelikler kullanılarak bu yapılabilir). Sonraki bölümde bileşik birincil anahtarı yapılandırmayı göreceğiz.

Bileşik anahtar, bir kurs için birden çok satıra ve bir eğitmen için birden çok satıra sahip olabilirken aynı eğitmen ve kurs için birden çok satıra sahip olamayarak sağlar. Birleştirme Enrollment varlığı kendi birincil anahtarını tanımlar, bu nedenle bu tür yinelemeler mümkündür. Bu tür yinelemeleri önlemek için yabancı anahtar alanlarına benzersiz bir dizin ekleyebilir veya ile benzer Enrollment bir birincil bileşik anahtarla yapılandırabilirsiniz. CourseAssignment Daha fazla bilgi için bkz. Dizinler.

Veritabanı bağlamını güncelleştirme

Data/SchoolContext.cs dosyasına aşağıdaki vurgulanmış kodu ekleyin:

using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity.Data
{
    public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }
        public DbSet<Department> Departments { get; set; }
        public DbSet<Instructor> Instructors { get; set; }
        public DbSet<OfficeAssignment> OfficeAssignments { get; set; }
        public DbSet<CourseAssignment> CourseAssignments { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Course>().ToTable("Course");
            modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
            modelBuilder.Entity<Student>().ToTable("Student");
            modelBuilder.Entity<Department>().ToTable("Department");
            modelBuilder.Entity<Instructor>().ToTable("Instructor");
            modelBuilder.Entity<OfficeAssignment>().ToTable("OfficeAssignment");
            modelBuilder.Entity<CourseAssignment>().ToTable("CourseAssignment");

            modelBuilder.Entity<CourseAssignment>()
                .HasKey(c => new { c.CourseID, c.InstructorID });
        }
    }
}

Bu kod yeni varlıkları ekler ve CourseAssignment varlığının bileşik birincil anahtarını yapılandırmaktadır.

Fluent API alternatifi hakkında

sınıfının yönteminde OnModelCreating yer alan kod EF davranışını yapılandırmak için fluent DbContext API'sini kullanır. Api genellikle aşağıdaki belgelerde yer alan örnekte olduğu gibi bir dizi yöntem çağrısını tek bir deyime dizelerken kullandığından "fluent" EF Core kullanılır:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .IsRequired();
}

Bu öğreticide, fluent API'yi yalnızca özniteliklerle yapalamayabilirsiniz veritabanı eşlemesi için kullanırsınız. Ancak, öznitelikleri kullanarak kullanabileceğiniz biçimlendirme, doğrulama ve eşleme kurallarının çoğunu belirtmek için fluent API'sini de kullanabilirsiniz. gibi bazı MinimumLength öznitelikler fluent API ile uygulanamamalıdır. Daha önce belirtildiği MinimumLength gibi şemayı değiştirmez, yalnızca bir istemci ve sunucu tarafı doğrulama kuralı uygular.

Bazı geliştiriciler varlık sınıflarını "temiz" tutmak için fluent API'yi özel olarak kullanmayı tercih eder. Öznitelikleri ve fluent API'yi istediğiniz zaman bir arada kullanabilirsiniz ve yalnızca fluent API kullanılarak yap 2 özelleştirme yapılabilir, ancak genel olarak önerilen yöntem bu iki yaklaşımdan birini seçmek ve bunu mümkün olduğunca tutarlı bir şekilde kullanmaktır. Her ikisini de kullanırsanız, çakışmanın olduğu her yerde API'nin öznitelikleri Fluent olduğunu unutmayın.

Öznitelikler ve Fluent API hakkında daha fazla bilgi için bkz. Yapılandırma yöntemleri.

İlişkileri Gösteren Varlık Diyagramı

Aşağıdaki çizimde, Power Tools'Entity Framework tamamlanmış School modeli için oluşturan diyagram gösterilmiştir.

Varlık diyagramı

Bire çok ilişki çizgilerinin (1 - ) yanı sıra, ve varlıkları ile Eğitmen ve Departman varlıkları arasındaki sıfır veya bire çok ilişki çizgisi (0,1 ile *) arasındaki bir-sıfır veya bir ilişki çizgisini * Instructor OfficeAssignment (1-0,1- *) burada da görebilir.

Test verileriyle çekirdek veritabanı

Oluşturduğunuz yeni varlıklar için çekirdek verileri sağlamak için Data/DbInitializer.cs dosyasındaki kodu aşağıdaki kodla değiştirin.

using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ContosoUniversity.Models;

namespace ContosoUniversity.Data
{
    public static class DbInitializer
    {
        public static void Initialize(SchoolContext context)
        {
            //context.Database.EnsureCreated();

            // Look for any students.
            if (context.Students.Any())
            {
                return;   // DB has been seeded
            }

            var students = new Student[]
            {
                new Student { FirstMidName = "Carson",   LastName = "Alexander",
                    EnrollmentDate = DateTime.Parse("2010-09-01") },
                new Student { FirstMidName = "Meredith", LastName = "Alonso",
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Arturo",   LastName = "Anand",
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Gytis",    LastName = "Barzdukas",
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Yan",      LastName = "Li",
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Peggy",    LastName = "Justice",
                    EnrollmentDate = DateTime.Parse("2011-09-01") },
                new Student { FirstMidName = "Laura",    LastName = "Norman",
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Nino",     LastName = "Olivetto",
                    EnrollmentDate = DateTime.Parse("2005-09-01") }
            };

            foreach (Student s in students)
            {
                context.Students.Add(s);
            }
            context.SaveChanges();

            var instructors = new Instructor[]
            {
                new Instructor { FirstMidName = "Kim",     LastName = "Abercrombie",
                    HireDate = DateTime.Parse("1995-03-11") },
                new Instructor { FirstMidName = "Fadi",    LastName = "Fakhouri",
                    HireDate = DateTime.Parse("2002-07-06") },
                new Instructor { FirstMidName = "Roger",   LastName = "Harui",
                    HireDate = DateTime.Parse("1998-07-01") },
                new Instructor { FirstMidName = "Candace", LastName = "Kapoor",
                    HireDate = DateTime.Parse("2001-01-15") },
                new Instructor { FirstMidName = "Roger",   LastName = "Zheng",
                    HireDate = DateTime.Parse("2004-02-12") }
            };

            foreach (Instructor i in instructors)
            {
                context.Instructors.Add(i);
            }
            context.SaveChanges();

            var departments = new Department[]
            {
                new Department { Name = "English",     Budget = 350000,
                    StartDate = DateTime.Parse("2007-09-01"),
                    InstructorID  = instructors.Single( i => i.LastName == "Abercrombie").ID },
                new Department { Name = "Mathematics", Budget = 100000,
                    StartDate = DateTime.Parse("2007-09-01"),
                    InstructorID  = instructors.Single( i => i.LastName == "Fakhouri").ID },
                new Department { Name = "Engineering", Budget = 350000,
                    StartDate = DateTime.Parse("2007-09-01"),
                    InstructorID  = instructors.Single( i => i.LastName == "Harui").ID },
                new Department { Name = "Economics",   Budget = 100000,
                    StartDate = DateTime.Parse("2007-09-01"),
                    InstructorID  = instructors.Single( i => i.LastName == "Kapoor").ID }
            };

            foreach (Department d in departments)
            {
                context.Departments.Add(d);
            }
            context.SaveChanges();

            var courses = new Course[]
            {
                new Course {CourseID = 1050, Title = "Chemistry",      Credits = 3,
                    DepartmentID = departments.Single( s => s.Name == "Engineering").DepartmentID
                },
                new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3,
                    DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID
                },
                new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3,
                    DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID
                },
                new Course {CourseID = 1045, Title = "Calculus",       Credits = 4,
                    DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID
                },
                new Course {CourseID = 3141, Title = "Trigonometry",   Credits = 4,
                    DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID
                },
                new Course {CourseID = 2021, Title = "Composition",    Credits = 3,
                    DepartmentID = departments.Single( s => s.Name == "English").DepartmentID
                },
                new Course {CourseID = 2042, Title = "Literature",     Credits = 4,
                    DepartmentID = departments.Single( s => s.Name == "English").DepartmentID
                },
            };

            foreach (Course c in courses)
            {
                context.Courses.Add(c);
            }
            context.SaveChanges();

            var officeAssignments = new OfficeAssignment[]
            {
                new OfficeAssignment {
                    InstructorID = instructors.Single( i => i.LastName == "Fakhouri").ID,
                    Location = "Smith 17" },
                new OfficeAssignment {
                    InstructorID = instructors.Single( i => i.LastName == "Harui").ID,
                    Location = "Gowan 27" },
                new OfficeAssignment {
                    InstructorID = instructors.Single( i => i.LastName == "Kapoor").ID,
                    Location = "Thompson 304" },
            };

            foreach (OfficeAssignment o in officeAssignments)
            {
                context.OfficeAssignments.Add(o);
            }
            context.SaveChanges();

            var courseInstructors = new CourseAssignment[]
            {
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Kapoor").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Harui").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Zheng").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Zheng").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Fakhouri").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Harui").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Abercrombie").ID
                    },
                new CourseAssignment {
                    CourseID = courses.Single(c => c.Title == "Literature" ).CourseID,
                    InstructorID = instructors.Single(i => i.LastName == "Abercrombie").ID
                    },
            };

            foreach (CourseAssignment ci in courseInstructors)
            {
                context.CourseAssignments.Add(ci);
            }
            context.SaveChanges();

            var enrollments = new Enrollment[]
            {
                new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alexander").ID,
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
                    Grade = Grade.A
                },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alexander").ID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
                    Grade = Grade.C
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alexander").ID,
                    CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Anand").ID,
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Anand").ID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                    Grade = Grade.B
                    },
                new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
                    CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Li").ID,
                    CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                    Grade = Grade.B
                    },
                    new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Justice").ID,
                    CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                    Grade = Grade.B
                    }
            };

            foreach (Enrollment e in enrollments)
            {
                var enrollmentInDataBase = context.Enrollments.Where(
                    s =>
                            s.Student.ID == e.StudentID &&
                            s.Course.CourseID == e.CourseID).SingleOrDefault();
                if (enrollmentInDataBase == null)
                {
                    context.Enrollments.Add(e);
                }
            }
            context.SaveChanges();
        }
    }
}

İlk öğreticide de gördüğümüz gibi, bu kodun çoğu yalnızca yeni varlık nesneleri oluşturur ve test için gereken özelliklere örnek verileri yükler. Çoka çok ilişkilerin nasıl iş bildirimlere sahip olduğunu fark edersiniz: kod, varlık kümelerini oluşturarak ve varlık Enrollments kümelerini CourseAssignment oluşturarak ilişkiler oluşturur.

Geçiş ekleme

Değişikliklerinizi kaydedin ve projeyi derleme. Ardından proje klasöründe komut penceresini açın ve komutunu girin migrations add (henüz update-database komutunu girmeyin):

dotnet ef migrations add ComplexDataModel

Olası veri kaybı hakkında bir uyarı alırsiniz.

An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.
Done. To undo this action, use 'ef migrations remove'

Bu noktada komutu database update çalıştırmayı denemiş olsaydık (henüz çalıştırmadıysanız) şu hatayı alırsınız:

ALTER TABLE deyimi, FOREIGN KEY kısıtlaması "FK_dbo. Course_dbo. Department_DepartmentID". Çakışma " dbo" tablosu olan "ContosoUniversity" veritabanında oluştu. Department", column 'DepartmentID'.

Bazen geçişleri mevcut verilerle yürütürken yabancı anahtar kısıtlamalarını karşılamak için veritabanına saplama verileri eklemeniz gerekir. yönteminde oluşturulan Up kod, tabloya null değerdilemez DepartmentID bir yabancı anahtar Course ekler. Kod çalıştırıldıklarında Kurs tablosunda zaten satırlar varsa işlem başarısız olur çünkü SQL Server sütuna null değer AddColumn koyamazsınız. Bu öğreticide geçişi yeni bir veritabanında çalıştırabilirsiniz, ancak bir üretim uygulamasında geçişin mevcut verileri işlemesini sağlarsınız, bu nedenle aşağıdaki yönlerde bunun nasıl gerçekleştirecekleri hakkında bir örnek yer alır.

Bu geçişin mevcut verilerle çalışması için kodu yeni sütuna varsayılan değer verecek şekilde değiştirmeli ve varsayılan departman olarak hareket etmek için "Temp" adlı bir saplama departmanı oluşturmanız gerekir. Sonuç olarak, yöntem çalıştır alındıktan sonra mevcut Kurs satırlarının hepsi "Geçici" Up bölümle ilişkili olur.

  • {timestamp}_ComplexDataModel.cs dosyasını açın.

  • DepartmentID sütununu Kurs tablosuna ekleyen kod satırına açıklama satırı yap.

    migrationBuilder.AlterColumn<string>(
        name: "Title",
        table: "Course",
        maxLength: 50,
        nullable: true,
        oldClrType: typeof(string),
        oldNullable: true);
                
    //migrationBuilder.AddColumn<int>(
    //    name: "DepartmentID",
    //    table: "Course",
    //    nullable: false,
    //    defaultValue: 0);
    
  • Department tablosu oluşturan kodun ardından aşağıdaki vurgulanmış kodu ekleyin:

    migrationBuilder.CreateTable(
        name: "Department",
        columns: table => new
        {
            DepartmentID = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            Budget = table.Column<decimal>(type: "money", nullable: false),
            InstructorID = table.Column<int>(nullable: true),
            Name = table.Column<string>(maxLength: 50, nullable: true),
            StartDate = table.Column<DateTime>(nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Department", x => x.DepartmentID);
            table.ForeignKey(
                name: "FK_Department_Instructor_InstructorID",
                column: x => x.InstructorID,
                principalTable: "Instructor",
                principalColumn: "ID",
                onDelete: ReferentialAction.Restrict);
        });
    
    migrationBuilder.Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())");
    // Default value for FK points to department created above, with
    // defaultValue changed to 1 in following AddColumn statement.
    
    migrationBuilder.AddColumn<int>(
        name: "DepartmentID",
        table: "Course",
        nullable: false,
        defaultValue: 1);
    

Bir üretim uygulamasında, Bölüm satırları eklemek ve Kurs satırlarını yeni Departman satırlarıyla ilişkilendirmek için kod veya betikler yazardınız. Daha sonra artık "Geçici" bölüme veya sütundaki varsayılan değere ihtiyacınız Course.DepartmentID olmayacaktır.

Değişikliklerinizi kaydedin ve projeyi derleme.

Bağlantı dizesini değiştirme

Artık sınıfında boş bir DbInitializer veritabanına yeni varlıklar için çekirdek verileri ekleyen yeni kodunuz var. EF'nin yeni bir boş veritabanı oluşturması için, bağlantı dizesinde veritabanının adını ContosoUniversity3 olarak veya kullanmakta olduğu bilgisayarda kullanmamış başka bir appsettings.json adla değiştirebilirsiniz.

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity3;Trusted_Connection=True;MultipleActiveResultSets=true"
  },

değişikliğinizi olarak appsettings.json kaydedin.

Not

Veritabanı adını değiştirmeye alternatif olarak veritabanını silebilirsiniz. SQL Server Nesne Gezgini (SSOX) veya CLI database drop komutunu kullanın:

dotnet ef database drop

Veritabanını güncelleştirme

Veritabanı adını değiştirdikten veya veritabanını sildikten sonra, geçişleri yürütmek database update için komut penceresinde komutunu çalıştırın.

dotnet ef database update

Yönteminin çalışmasına ve DbInitializer.Initialize yeni veritabanını doldurmak için uygulamayı çalıştırın.

Daha önce olduğu gibi veritabanını SSOX'te açın ve tüm tabloların oluşturulmuş olduğunu görmek için Tablolar düğümünü genişletin. (Daha önceki bir zamanda SSOX açıksa Yenile düğmesine tıklayın.)

SSOX'ta tablolar

Veritabanının çekirdeğini başlatan başlatıcı kodunu tetiklemek için uygulamayı çalıştırın.

CourseAssignment tablosuna sağ tıklayın ve içinde veri olduğunu doğrulamak için Verileri Görüntüle'yi seçin.

SSOX'de CourseAssignment verileri

Kodu alma

Tamamlanan uygulamayı indirme veya görüntüleme.

Sonraki adımlar

Bu öğreticide şunları yaptınız:

  • Özelleştirilmiş Veri modeli
  • Öğrenci varlığında değişiklik yapıldı
  • Eğitmen varlığı oluşturuldu
  • OfficeAssignment varlığı oluşturuldu
  • Değiştirilmiş Kurs varlığı
  • Departman varlığı oluşturuldu
  • Değiştirilen Kayıt varlığı
  • Veritabanı bağlamı güncelleştirildi
  • Test verileriyle çekirdek veritabanı
  • Geçiş eklendi
  • Bağlantı dizesi değiştirildi
  • Veritabanı güncelleştirildi

İlgili verilere erişme hakkında daha fazla bilgi edinmek için sonraki öğreticiye ilerleyin.