Aracılığıyla paylaş


ASP.NET MVC Uygulaması için Entity Framework Veri Modeli Oluşturma (1/10)

tarafından Tom Dykstra

Contoso University örnek web uygulaması, Entity Framework 5 ve Visual Studio 2012 kullanarak ASP.NET MVC 4 uygulamalarının nasıl oluşturulacağını gösterir. Örnek uygulama, kurgusal bir Contoso Üniversitesi için bir web sitesidir. Öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Bu öğretici serisinde Contoso University örnek uygulamasının nasıl derlenenleri açıklanmaktadır.

Önce KodLa

Entity Framework'teki verilerle çalışmanın üç yolu vardır: Önce Veritabanı, Önce Model ve İlk Kod. Bu öğretici, Önce Kod'a yöneliktir. Bu iş akışları arasındaki farklar hakkında bilgi edinmek ve senaryonuz için en iyi iş akışını seçme yönergeleri için bkz . Entity Framework Geliştirme İş Akışları.

MVC

Örnek uygulama ASP.NET MVC üzerinde oluşturulmuş. ASP.NET Web Forms modeliyle çalışmayı tercih ediyorsanız Bkz . Model Bağlama ve Web Forms öğretici serisi ve veri erişimi içerik eşlemesini ASP.NET.

Yazılım sürümleri

Öğreticide gösterilmiştir Ayrıca ile de çalışır
Windows 8 Windows 7
Visual Studio 2012 Web için Visual Studio 2012 Express. Vs 2012 veya Web için VS 2012 Express'iniz yoksa bu, Windows Azure SDK'sı tarafından otomatik olarak yüklenir. Visual Studio 2013 çalışmalıdır, ancak öğretici bununla test edilmemiştir ve bazı menü seçimleri ve iletişim kutuları farklıdır. Windows Azure dağıtımı için Windows Azure SDK'sının VS 2013 sürümü gereklidir.
.NET 4.5 Gösterilen özelliklerin çoğu .NET 4'te çalışır ancak bazıları çalışmaz. Örneğin, EF'teki sabit listesi desteği .NET 4.5 gerektirir.
Entity Framework 5
Windows Azure SDK 2.1 Windows Azure dağıtım adımlarını atlarsanız SDK'ya ihtiyacınız yoktur. SDK'nın yeni bir sürümü yayımlandığında, bağlantı daha yeni sürümü yükler. Bu durumda, bazı yönergeleri yeni kullanıcı arabirimine ve özelliklere uyarlamanız gerekebilir.

Sorular

Öğreticiyle doğrudan ilgili olmayan sorularınız varsa bunları ASP.NET Entity Framework forumu, Entity Framework ve LINQ to Entities forumu veya StackOverflow.com gönderebilirsiniz.

İlgili kaynaklar

Onaylar için serideki son öğreticiye ve VB hakkında bir nota bakın.

Contoso University Web Uygulaması

Bu öğreticilerde oluşturacağın uygulama basit bir üniversite web sitesidir.

Kullanıcılar öğrenci, kurs ve eğitmen bilgilerini görüntüleyebilir ve güncelleştirebilir. Oluşturacağınız ekranlardan birkaçı aşağıdadır.

Students_Index_page

Örnek Contoso Üniversitesi web uygulamasının Öğrenciler arama sayfasını ve Yeni Öğrenci Oluştur sayfasını gösteren ekran görüntüleri.

Bu sitenin kullanıcı arabirimi stili, yerleşik şablonlar tarafından oluşturulana yakın tutuldu, böylece öğretici temel olarak Entity Framework'ün nasıl kullanılacağına odaklanabiliyordu.

Önkoşullar

Bu öğreticideki yol tarifleri ve ekran görüntüleri, Temmuz 2013 itibarıyla yüklenen en son güncelleştirme ve .NET için Azure SDK ile Birlikte Web için Visual Studio 2012 veya Visual Studio 2012 Express kullandığınızı varsayar. Tüm bunları aşağıdaki bağlantıyla alabilirsiniz:

.NET için Azure SDK (Visual Studio 2012)

Visual Studio yüklüyse, yukarıdaki bağlantı eksik bileşenleri yükler. Visual Studio'nuz yoksa, bağlantı Web için Visual Studio 2012 Express'i yükler. Visual Studio 2013'i kullanabilirsiniz, ancak gerekli yordamlardan ve ekranlardan bazıları farklılık gösterir.

MVC Web Uygulaması Oluşturma

Visual Studio'yu açın ve ASP.NET MVC 4 Web Uygulaması şablonunu kullanarak "ContosoUniversity" adlı yeni bir C# projesi oluşturun. .NET Framework 4.5'i hedeflediğinizden emin olun (özellikleri kullanacaksınız enum ve bunun için .NET 4.5 gerekir).

New_project_dialog_box

Yeni ASP.NET MVC 4 Projesi iletişim kutusunda İnternet Uygulaması şablonunu seçin.

Razor görünüm altyapısını seçili bırakın ve Birim testi projesi oluştur onay kutusunu temiz bırakın.

Tamam'a tıklayın.

Project_template_options

Site Stilini Ayarlama

Birkaç basit değişiklik site menüsünü, düzenini ve giriş sayfasını ayarlar.

Views\Shared\_Layout.cshtml dosyasını açın ve dosyanın içeriğini aşağıdaki kodla değiştirin. Değişiklikler vurgulanır.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - Contoso University</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("Contoso University", "Index", "Home")</p>
                </div>
                <div class="float-right">
                    <section id="login">
                        @Html.Partial("_LoginPartial")
                    </section>
                    <nav>
                        <ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Students", "Index", "Student")</li>
                            <li>@Html.ActionLink("Courses", "Index", "Course")</li>
                            <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
                            <li>@Html.ActionLink("Departments", "Index", "Department")</li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - Contoso University</p>
                </div>
            </div>
        </footer>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

Bu kod aşağıdaki değişiklikleri yapar:

  • "my ASP.NET MVC Application" ve "your logo here" şablon örneklerini "Contoso University" ile değiştirir.
  • Öğreticinin ilerleyen bölümlerinde kullanılacak birkaç eylem bağlantısı ekler.

Views\Home\Index.cshtml içinde, ASP.NET ve MVC hakkındaki şablon paragraflarını ortadan kaldırmak için dosyanın içeriğini aşağıdaki kodla değiştirin:

@{
    ViewBag.Title = "Home Page";
}
@section featured {
    <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <h1>@ViewBag.Title.</h1>
                <h2>@ViewBag.Message</h2>
            </hgroup>
        </div>
    </section>
}

Controllers\HomeController.cs bölümünde, aşağıdaki örnekte gösterildiği gibi Eylem yöntemindeki Index değerini ViewBag.Message "Contoso Üniversitesine Hoş Geldiniz!" olarak değiştirin:

public ActionResult Index()
{
    ViewBag.Message = "Welcome to Contoso University";

    return View();
}

Siteyi çalıştırmak için CTRL+F5 tuşlarına basın. Ana menünün olduğu giriş sayfasını görürsünüz.

Contoso_University_home_page

Veri Modeli Oluşturma

Daha sonra Contoso Üniversitesi uygulaması için varlık sınıfları oluşturacaksınız. Aşağıdaki üç varlıkla başlayacaksınız:

Class_diagram

varlıklar arasında Student Enrollment bire çok ilişkisi ve varlıklar arasında Course Enrollment bire çok ilişkisi vardır. Başka bir deyişle, bir öğrenci herhangi bir sayıda kursa kaydedilebilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.

Aşağıdaki bölümlerde bu varlıkların her biri için bir sınıf oluşturacaksınız.

Not

Bu varlık sınıflarının tümünü oluşturmayı tamamlamadan önce projeyi derlemeye çalışırsanız, derleyici hataları alırsınız.

Öğrenci Varlığı

Student_entity

Modeller klasöründe Student.cs oluşturun ve var olan kodu aşağıdaki kodla değiştirin:

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int StudentID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
        
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

özelliği, StudentID veritabanı tablosunun bu sınıfa karşılık gelen birincil anahtar sütunu olur. Varsayılan olarak, Entity Framework veya classname ID adlı ID bir özelliği birincil anahtar olarak yorumlar.

Enrollments özelliği bir gezinti özelliğidir. Gezinti özellikleri, bu varlıkla ilgili diğer varlıkları barındırır. Bu durumda, bir varlığın Enrollments özelliği bu varlıkla ilgili Student tüm Enrollment varlıkları barındırır.Student Başka bir deyişle, veritabanındaki belirli Student bir satırda ilişkili Enrollment iki satır varsa (yabancı anahtar sütununda o öğrencinin birincil anahtar değerini içeren satırlar StudentID ), bu varlığın Student Enrollments gezinti özelliği bu iki Enrollment varlığı içerir.

Gezinti özellikleri genellikle olarak virtual tanımlanır, böylece gecikmeli yükleme gibi belirli Entity Framework işlevselliğinden yararlanabilirler. (Gecikmeli yükleme daha sonraBu serinin devamında İlgili Veriler öğreticisi okunması.

Bir gezinti özelliği birden çok varlığı barındırabiliyorsa (çoka çok veya bire çok ilişkilerde olduğu gibi), türü gibi girdilerin eklenebileceği, silinebileceği ve güncelleştirilebileceği ICollectionbir liste olmalıdır.

Kayıt Varlığı

Enrollment_entity

Modeller klasöründe Enrollment.cs oluşturun ve mevcut kodu aşağıdaki kodla değiştirin:

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; }
        public Grade? Grade { get; set; }
        
        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }
}

Grade özelliği bir sabit listesidir. Tür bildiriminden Grade sonraki soru işareti özelliğin Grade null atanabilir olduğunu gösterir. Null olan bir not sıfırdan farklıdır; null değeri, notların bilinmediği veya henüz atanmadığı anlamına gelir.

StudentID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirStudent. Bir Enrollment varlık bir Student varlıkla ilişkilendirildiğinden özellik yalnızca tek Student bir varlığı barındırabilir (daha önce gördüğünüz gezinti özelliğinin Student.Enrollments aksine, birden çok Enrollment varlığı barındırabilir).

CourseID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirCourse. Bir Enrollment varlık bir Course varlıkla ilişkilendirilir.

Kurs Varlığı

Course_entity

Modeller klasöründe, mevcut kodu aşağıdaki kodla değiştirerek Course.cs oluşturun:

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

namespace ContosoUniversity.Models
{
    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; }
    }
}

Enrollments özelliği bir gezinti özelliğidir. Bir Course varlık, herhangi bir sayıda Enrollment varlıkla ilişkilendirilebilir.

[DatabaseGenerated(DatabaseGeneratedOption) hakkında daha fazla bilgi vereceğiz. Yok)] özniteliğini sonraki öğreticide bulabilirsiniz. Temel olarak, bu öznitelik veritabanının oluşturması yerine kursun birincil anahtarını girmenizi sağlar.

Veritabanı Bağlamı Oluşturma

Belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıf, veritabanı bağlam sınıfıdır. Bu sınıfı System.Data.Entity.DbContext sınıfından türeterek oluşturursunuz. Kodunuzda, veri modeline hangi varlıkların dahil olduğunu belirtirsiniz. Ayrıca belirli Entity Framework davranışını özelleştirebilirsiniz. Bu projede sınıfı olarak adlandırılır SchoolContext.

DAL adlı bir klasör oluşturun (Veri Erişim Katmanı için). Bu klasörde SchoolContext.cs adlı yeni bir sınıf dosyası oluşturun ve var olan kodu aşağıdaki kodla değiştirin:

using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ContosoUniversity.DAL
{
    public class SchoolContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

Bu kod, her varlık kümesi için bir DbSet özelliği oluşturur. Entity Framework terminolojisinde varlık kümesi genellikle bir veritabanı tablosuna, varlık ise tablodaki bir satıra karşılık gelir.

modelBuilder.Conventions.Remove OnModelCreating yöntemindeki deyimi, tablo adlarının çoğullaştırılmasını engeller. Bunu yapmadıysanız, oluşturulan tablolar , Coursesve Enrollmentsolarak adlandırılırStudents. Bunun yerine, tablo adları , Courseve EnrollmentolurStudent. Geliştiriciler tablo adlarının çoğullaştırılıp çoğullaştırılmaması konusunda aynı fikirde değildir. Bu öğreticide tekil form kullanılır, ancak önemli olan nokta, bu kod satırını ekleyerek veya atlayarak hangi formu tercih ettiğinizi seçebilmenizdir.

SQL Server Express LocalDB

LocalDB , SQL Server Express Veritabanı Altyapısı'nın isteğe bağlı olarak başlayan ve kullanıcı modunda çalışan basit bir sürümüdür. LocalDB, veritabanlarıyla .mdf dosyaları olarak çalışmanızı sağlayan özel bir SQL Server Express yürütme modunda çalışır. Genellikle, LocalDB veritabanı dosyaları bir web projesinin App_Data klasöründe tutulur. SQL Server Express'teki kullanıcı örneği özelliği, .mdf dosyalarla çalışmanızı da sağlar, ancak kullanıcı örneği özelliği kullanım dışıdır; bu nedenle, .mdf dosyalarıyla çalışmak için LocalDB önerilir.

Sql Server Express genellikle üretim web uygulamaları için kullanılmaz. LocalDB özellikle bir web uygulamasıyla üretim kullanımı için önerilmez çünkü IIS ile çalışacak şekilde tasarlanmamıştır.

Visual Studio 2012 ve sonraki sürümlerde LocalDB varsayılan olarak Visual Studio ile yüklenir. Visual Studio 2010 ve önceki sürümlerde SQL Server Express (LocalDB olmadan) varsayılan olarak Visual Studio ile yüklenir; Visual Studio 2010 kullanıyorsanız el ile yüklemeniz gerekir.

Bu öğreticide, veritabanının App_Data klasöründe .mdf dosyası olarak depolanabilmesi için LocalDB ile çalışacaksınız. Kök Web.config dosyasını açın ve aşağıdaki örnekte gösterildiği gibi koleksiyona connectionStrings yeni bir bağlantı dizesi ekleyin. (Güncelleştirme yaptığınızdan emin olunKök proje klasöründeki Web.config dosyası. Görünümler alt klasöründe güncelleştirmeniz gerekmeyen bir Web.config dosyası da vardır.)

<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ContosoUniversity.mdf" providerName="System.Data.SqlClient" />

Varsayılan olarak, Entity Framework sınıfıylaSchoolContext (bu proje için) aynı DbContext adlı bir bağlantı dizesi arar. Eklediğiniz bağlantı dizesi, App_Data klasöründe bulunan ContosoUniversity.mdf adlı bir LocalDB veritabanını belirtir. Daha fazla bilgi için bkz . ASP.NET Web Uygulamaları için SQL Server Bağlantı Dizeleri.

aslında bağlantı dizesi belirtmeniz gerekmez. bağlantı dizesi sağlamazsanız Entity Framework sizin için bir tane oluşturur; ancak veritabanı uygulamanızın App_data klasöründe olmayabilir. Veritabanının nerede oluşturulacağı hakkında bilgi için bkz . Yeni Veritabanına İlk Kod.

Koleksiyonun connectionStrings ayrıca üyelik veritabanı için kullanılan adlı DefaultConnection bir bağlantı dizesi vardır. Bu öğreticide üyelik veritabanını kullanmayacaksınız. İki bağlantı dizesi arasındaki tek fark, veritabanı adı ve ad özniteliği değeridir.

İlk Kod Geçişini Ayarlama ve Yürütme

Bir uygulamayı ilk kez geliştirmeye başladığınızda veri modeliniz sık sık değişir ve model her değiştiğinde veritabanıyla eşitlenmez. Entity Framework'ünü, veri modelini her değiştirdiğinizde veritabanını otomatik olarak bırakacak ve yeniden oluşturacak şekilde yapılandırabilirsiniz. Test verileri kolayca yeniden oluşturulduğundan geliştirmenin erken aşamalarında bu sorun olmaz, ancak üretime dağıttıktan sonra genellikle veritabanını bırakmadan veritabanı şemasını güncelleştirmek istersiniz. Geçişler özelliği, Code First'un veritabanını bırakmadan ve yeniden oluşturmadan güncelleştirmesini sağlar. Yeni bir projenin geliştirme döngüsünün başlarında DropCreateDatabaseIfModelChanges kullanarak modelin her değiştiğinde veritabanını bırakmak, yeniden oluşturmak ve yeniden görmek isteyebilirsiniz. Uygulamanızı dağıtmaya hazır olduğunuzda geçişler yaklaşımına dönüştürebilirsiniz. Bu öğreticide yalnızca geçişleri kullanacaksınız. Daha fazla bilgi için bkz . Code First Migrations and Migrations Screencast Series.

İlk Kod Geçişlerini Etkinleştirme

  1. Araçlar menüsünden NuGet Paket Yöneticisi’ne ve ardından Paket Yöneticisi Konsolu’na tıklayın.

    Selecting_Package_Manager_Console

  2. PM> İstemde aşağıdaki komutu girin:

    enable-migrations -contexttypename SchoolContext
    

    enable-migrations komutu

    Bu komut ContosoUniversity projesinde bir Migrations klasörü oluşturur ve bu klasöre Geçişleri yapılandırmak için düzenleyebileceğiniz bir Configuration.cs dosyası yerleştirir.

    Geçişler klasörü

    sınıfı, Configuration veritabanı oluşturulduğunda ve bir veri modeli değiştikten sonra her güncelleştirildiğinde çağrılan bir yöntem içerir Seed .

    internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.Models.SchoolContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }
    
        protected override void Seed(ContosoUniversity.Models.SchoolContext 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" }
            //    );
            //
        }
    }
    

    Bu Seed yöntemin amacı, Code First tarafından oluşturulan veya güncelleştirilen test verilerini veritabanına eklemenize olanak tanımaktır.

Seed Yöntemini Ayarlama

Seed yöntemi, Code First Migrations veritabanını oluşturduğunda ve veritabanını en son geçişe güncelleştirdiğinde çalışır. Seed yönteminin amacı, uygulama veritabanına ilk kez erişmeden önce tablolarınıza veri eklemenize olanak tanımaktır.

Code First'in önceki sürümlerinde, Geçişler yayımlanmadan önce test verileri ekleme yöntemleri yaygındı Seed , çünkü geliştirme sırasında yapılan her model değişikliğinde veritabanı sıfırdan tamamen silinip yeniden oluşturulması gerekiyordu. İlk Kod Geçişleri ile, test verileri veritabanı değiştikten sonra korunur, bu nedenle test verilerinin Seed yöntemine dahil edilmesi genellikle gerekli değildir. Aslında, veritabanını üretime dağıtmak için Migrations'ı kullanacaksanız yönteminin Seed test verileri eklemesini istemezsinizSeed, çünkü yöntem üretimde çalışacaktır. Bu durumda yönteminin Seed veritabanına yalnızca üretime eklenmesini istediğiniz verileri eklemesini istersiniz. Örneğin, uygulama üretim ortamında kullanıma sunulduğunda veritabanının tabloya Department gerçek departman adlarını eklemesini isteyebilirsiniz.

Bu öğreticide dağıtım için Geçişler'i kullanacaksınız, ancak yönteminiz Seed çok fazla veriyi el ile eklemek zorunda kalmadan uygulama işlevselliğinin nasıl çalıştığını görmeyi kolaylaştırmak için test verilerini yine de ekler.

  1. Configuration.cs dosyasının içeriğini, test verilerini yeni veritabanına yükleyecek olan aşağıdaki kodla değiştirin.

    namespace ContosoUniversity.Migrations
    {
       using System;
       using System.Collections.Generic;
       using System.Data.Entity.Migrations;
       using System.Linq;
       using ContosoUniversity.Models;
    
       internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
       {
          public Configuration()
          {
             AutomaticMigrationsEnabled = false;
          }
    
          protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
          {
             var students = new List<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-08-11") }
                };
             students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
             context.SaveChanges();
    
             var courses = new List<Course>
                {
                    new Course {CourseID = 1050, Title = "Chemistry",      Credits = 3, },
                    new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, },
                    new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, },
                    new Course {CourseID = 1045, Title = "Calculus",       Credits = 4, },
                    new Course {CourseID = 3141, Title = "Trigonometry",   Credits = 4, },
                    new Course {CourseID = 2021, Title = "Composition",    Credits = 3, },
                    new Course {CourseID = 2042, Title = "Literature",     Credits = 4, }
                };
             courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s));
             context.SaveChanges();
    
             var enrollments = new List<Enrollment>
                {
                    new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").StudentID, 
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
                        Grade = Grade.A 
                    },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, 
                        Grade = Grade.C 
                     },                            
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                        CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, 
                        Grade = Grade.B
                     },
                     new Enrollment { 
                         StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                        CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment { 
                         StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                        CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                        CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                        Grade = Grade.B         
                     },
                    new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID,
                        CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                        Grade = Grade.B         
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Li").StudentID,
                        CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                        Grade = Grade.B         
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Justice").StudentID,
                        CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                        Grade = Grade.B         
                     }
                };
    
             foreach (Enrollment e in enrollments)
             {
                var enrollmentInDataBase = context.Enrollments.Where(
                    s =>
                         s.Student.StudentID == e.StudentID &&
                         s.Course.CourseID == e.CourseID).SingleOrDefault();
                if (enrollmentInDataBase == null)
                {
                   context.Enrollments.Add(e);
                }
             }
             context.SaveChanges();
          }
       }
    }
    

    Seed yöntemi, veritabanı bağlam nesnesini giriş parametresi olarak alır ve yöntemdeki kod veritabanına yeni varlıklar eklemek için bu nesneyi kullanır. Kod, her varlık türü için yeni varlık koleksiyonu oluşturur, bunları uygun DbSet özelliğine ekler ve ardından değişiklikleri veritabanına kaydeder. Burada olduğu gibi, her varlık grubundan sonra SaveChanges yöntemini çağırmak gerekli değildir, ancak bunu yapmak, kod veritabanına yazarken bir özel durum oluşursa sorunun kaynağını bulmanıza yardımcı olur.

    Veri ekleyen deyimlerden bazıları, "upsert" işlemi gerçekleştirmek için AddOrUpdate yöntemini kullanır. Yöntemi her geçişle çalıştığından Seed , eklemeye çalıştığınız satırlar veritabanını oluşturan ilk geçiş sonrasında zaten orada olacağı için veri ekleyemezsiniz. "upsert" işlemi, zaten var olan bir satır eklemeye çalıştığınızda oluşabilecek hataları önler, ancak uygulamayı test ederken yapmış olabileceğiniz verilerde yaptığınız değişiklikleri geçersiz kılar . Bazı tablolardaki test verileriyle bunun olmasını istemeyebilirsiniz: Bazı durumlarda test sırasında verileri değiştirdiğinizde, veritabanı güncelleştirmeleri sonrasında değişikliklerinizin kalmasını istersiniz. Bu durumda, koşullu ekleme işlemi yapmak istiyorsunuz: yalnızca henüz yoksa bir satır ekleyin. Seed yöntemi her iki yaklaşımı da kullanır.

    AddOrUpdate yöntemine geçirilen ilk parametre, bir satırın zaten var olup olmadığını denetlemek için kullanılacak özelliği belirtir. Sağladığınız test öğrenci verileri için, LastName listedeki her soyadı benzersiz olduğundan özellik bu amaçla kullanılabilir:

    context.Students.AddOrUpdate(p => p.LastName, s)
    

    Bu kod, soyadlarının benzersiz olduğunu varsayar. Soyadı yinelenen bir öğrenciyi el ile eklerseniz, bir sonraki geçiş işleminizi gerçekleştirdiğinizde aşağıdaki özel durumla karşınıza çıkar.

    Sıra birden fazla öğe içeriyor

    Yöntemi hakkında AddOrUpdate daha fazla bilgi için Julie Lerman'ın blogunda EF 4.3 AddOrUpdate Yöntemi ile ilgilenme bölümüne bakın.

    Varlık ekleyen Enrollment kod yöntemini AddOrUpdate kullanmaz. Bir varlığın zaten var olup olmadığını denetler ve yoksa varlığı ekler. Bu yaklaşım, geçişler çalıştırıldığında kayıt notlarında yaptığınız değişiklikleri korur. Kod, Listenin her üyesi arasında Enrollmentdöngü oluşturur ve kayıt veritabanında bulunmazsa kaydı veritabanına ekler. Veritabanını ilk kez güncelleştirdiğinizde veritabanı boş olur, bu nedenle her kaydı ekler.

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

    Yöntemin Seed hatalarını ayıklama ve "Alexander Carson" adlı iki öğrenci gibi yedekli verileri işleme hakkında bilgi için Rick Anderson'ın blogundaki Seeding and Debugging Entity Framework (EF) DB'lerine bakın.

  2. Projeyi derleyin.

İlk Geçişi Oluşturma ve Yürütme

  1. Paket Yöneticisi Konsolu penceresinde aşağıdaki komutları girin:

    add-migration InitialCreate
    update-database
    

    Paket Yöneticisi Konsolu penceresini gösteren ekran görüntüsü. Komutlar kısa çizgi geçişi alt çizgi ekler İlk Oluşturma ve güncelleştirme kısa çizgi veritabanı vurgulanır.

    Komutu Migrations add-migration klasörüne veritabanını oluşturan kodu içeren bir [DateStamp]_InitialCreate.cs dosyası ekler. İlk parametre (InitialCreate) dosya adı için kullanılır ve istediğiniz gibi olabilir; genellikle geçişte yapılan işlemleri özetleyen bir sözcük veya tümcecik seçersiniz. Örneğin, sonraki bir geçişi "AddDepartmentTable" olarak adlandırabilirsiniz.

    İlk geçiş ile Migrations klasörü

    Up sınıfının yöntemiInitialCreate, veri modeli varlık kümelerine karşılık gelen veritabanı tablolarını oluşturur ve Down yöntemi bunları siler. Geçişler, geçiş için veri modeli değişikliklerini uygulamak için yöntemini çağırır Up . Güncelleştirmeyi geri almak için bir komut girdiğinizde Migrations yöntemini çağırır Down . Aşağıdaki kod dosyanın içeriğini InitialCreate gösterir:

    namespace ContosoUniversity.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class InitialCreate : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                    "dbo.Student",
                    c => new
                        {
                            StudentID = c.Int(nullable: false, identity: true),
                            LastName = c.String(),
                            FirstMidName = c.String(),
                            EnrollmentDate = c.DateTime(nullable: false),
                        })
                    .PrimaryKey(t => t.StudentID);
                
                CreateTable(
                    "dbo.Enrollment",
                    c => new
                        {
                            EnrollmentID = c.Int(nullable: false, identity: true),
                            CourseID = c.Int(nullable: false),
                            StudentID = c.Int(nullable: false),
                            Grade = c.Int(),
                        })
                    .PrimaryKey(t => t.EnrollmentID)
                    .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
                    .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true)
                    .Index(t => t.CourseID)
                    .Index(t => t.StudentID);
                
                CreateTable(
                    "dbo.Course",
                    c => new
                        {
                            CourseID = c.Int(nullable: false),
                            Title = c.String(),
                            Credits = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => t.CourseID);
                
            }
            
            public override void Down()
            {
                DropIndex("dbo.Enrollment", new[] { "StudentID" });
                DropIndex("dbo.Enrollment", new[] { "CourseID" });
                DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student");
                DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course");
                DropTable("dbo.Course");
                DropTable("dbo.Enrollment");
                DropTable("dbo.Student");
            }
        }
    }
    

    update-database komutu veritabanını oluşturmak için yöntemini çalıştırır Up ve ardından veritabanını doldurmak için yöntemini çalıştırırSeed.

Artık veri modeliniz için bir SQL Server veritabanı oluşturuldu. Veritabanının adı ContosoUniversity'dir ve .mdf dosyası projenizin App_Data klasöründedir çünkü bağlantı dizesi belirttiğiniz dosya budur.

Veritabanını Visual Studio'da görüntülemek için Sunucu Gezgini veya SQL Server Nesne Gezgini (SSOX) kullanabilirsiniz. Bu öğreticide Sunucu Gezgini'ni kullanacaksınız. Web için Visual Studio Express 2012'de Sunucu Gezgini, Veritabanı Gezgini olarak adlandırılır.

  1. Görünüm menüsünde Sunucu Gezgini'ne tıklayın.

  2. Bağlantı Ekle simgesine tıklayın.

    Veritabanı Gezgini penceresini gösteren ekran görüntüsü. Bağlantı Ekle simgesi vurgulanır.

  3. Veri Kaynağı Seç iletişim kutusu istenirse, Microsoft SQL Server'a ve ardından Devam'a tıklayın.

    Veri Kaynağı Seç iletişim kutusunu gösteren ekran görüntüsü. Microsoft S Q L Server veri kaynağı seçilir.

  4. Bağlantı Ekle iletişim kutusunda, Sunucu Adı için (localdb)\v11.0 girin. Veritabanı adı seçin veya girin altında ContosoUniversity'yi seçin.

    Bağlantı Ekle iletişim kutusunu gösteren ekran görüntüsü. Örnek Sunucu adı ve Contoso University veritabanı vurgulanır.

  5. Tamam'a tıklayın.

  6. SchoolContext'i ve ardından Tablolar'ı genişletin.

    Sunucu Gezgini sayfasını gösteren ekran görüntüsü. Okul Bağlamı ve Tablolar sekmeleri genişletilir.

  7. Oluşturulan sütunları ve tabloya eklenen satırları görmek için Öğrenci tablosuna sağ tıklayın ve Tablo Verilerini Göster'e tıklayın.

    Öğrenci tablosu

Öğrenci Denetleyicisi ve Görünümleri Oluşturma

Sonraki adım, uygulamanızda bu tablolardan biriyle çalışabilen bir ASP.NET MVC denetleyicisi ve görünümleri oluşturmaktır.

  1. Denetleyici Student oluşturmak için, Çözüm Gezgini'da Denetleyiciler klasörüne sağ tıklayın, Ekle'yi seçin ve denetleyici'ye tıklayın. Denetleyici Ekle iletişim kutusunda, aşağıdaki seçimleri yapın ve Ekle'ye tıklayın:

    • Denetleyici adı: StudentController.

    • Şablon: Entity Framework kullanarak okuma/yazma eylemleri ve görünümleri olan MVC denetleyicisi.

    • Model sınıfı: Öğrenci (ContosoUniversity.Models). (Açılan listede bu seçeneği görmüyorsanız projeyi derleyin ve yeniden deneyin.)

    • Veri bağlamı sınıfı: SchoolContext (ContosoUniversity.Models).

    • Görünümler: Razor (CSHTML). (Varsayılan değerdir.)

      Add_Controller_dialog_box_for_Student_controller

  2. Visual Studio Controllers\StudentController.cs dosyasını açar. Veritabanı bağlam nesnesinin örneğini oluşturan bir sınıf değişkeni oluşturulduğunu görürsünüz:

    private SchoolContext db = new SchoolContext();
    

    Eylem yöntemi, Index veritabanı bağlam örneğinin özelliğini okuyarak Students Öğrenciler varlık kümesinden öğrencilerin listesini alır:

    public ViewResult Index()
    {
        return View(db.Students.ToList());
    }
    

    Student\Index.cshtml görünümü bu listeyi bir tabloda görüntüler:

    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
                @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
            </td>
        </tr>
    }
    
  3. Projeyi çalıştırmak için CTRL+F5 tuşlarına basın.

    Yöntemin eklendiği test verilerini görmek için Öğrenciler sekmesine Seed tıklayın.

    Öğrenci Dizini sayfası

Kurallar

Entity Framework'ün sizin için eksiksiz bir veritabanı oluşturabilmesi için yazmanız gereken kod miktarı, Entity Framework'ün yaptığı kurallar veya varsayımlar nedeniyle çok azdır. Bunlardan bazıları önceden not edilmiştir:

  • Varlık sınıfı adlarının çoğullaştırılmış formları tablo adları olarak kullanılır.
  • Varlık özelliği adları sütun adları için kullanılır.
  • veya classname ID adlı ID varlık özellikleri birincil anahtar özellikleri olarak kabul edilir.

Kuralların geçersiz kılınabileceğini gördünüz (örneğin, tablo adlarının çoğullaştırılmaması gerektiğini belirttiniz) ve kurallar ve bunları geçersiz kılma hakkında daha fazla bilgi edinmek için bu serinin devamında Daha Karmaşık Bir Veri Modeli Oluşturma öğreticisinde bulabilirsiniz. Daha fazla bilgi için bkz. Code First Conventions.

Özet

Şimdi verileri depolamak ve görüntülemek için Entity Framework ve SQL Server Express kullanan basit bir uygulama oluşturdunuz. Aşağıdaki öğreticide temel CRUD (oluşturma, okuma, güncelleştirme, silme) işlemlerini gerçekleştirmeyi öğreneceksiniz. Bu sayfanın en altına geri bildirim bırakabilirsiniz. Lütfen öğreticinin bu bölümünü nasıl beğendiğiniz ve nasıl geliştirebileceğimizi bize bildirin.

Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi İçerik Eşlemesi'nde bulunabilir.