Sdílet prostřednictvím


Vytvoření datového modelu Entity Framework pro aplikaci ASP.NET MVC (1 z 10)

Tom Dykstra

Poznámka

Je k dispozici novější verze této série kurzů pro Visual Studio 2013, Entity Framework 6 a MVC 5.

Ukázková webová aplikace Contoso University ukazuje, jak vytvářet aplikace ASP.NET MVC 4 pomocí entity frameworku 5 a sady Visual Studio 2012. Ukázková aplikace je web fiktivní univerzity Contoso. Zahrnuje funkce, jako je přijímání studentů, vytváření kurzů a zadání instruktora. Tato série kurzů vysvětluje, jak sestavit ukázkovou aplikaci Contoso University.

Code First

S daty v Entity Frameworku můžete pracovat třemi způsoby: Database First, Model First a Code First. Tento kurz je určený pro Code First. Informace o rozdílech mezi těmito pracovními postupy a pokyny k výběru nejvhodnějšího pracovního postupu pro váš scénář najdete v tématu Vývojové pracovní postupy entity frameworku.

MVC

Ukázková aplikace je postavená na ASP.NET MVC. Pokud raději pracujete s modelem ASP.NET Web Forms, projděte si řadu kurzů o vazbách a Web Forms modelu a ASP.NET Mapě obsahu přístupu k datům.

Verze softwaru

Zobrazeno v kurzu Funguje také s
Windows 8 Windows 7
Visual Studio 2012 Visual Studio 2012 Express for Web. Pokud ještě nemáte VS 2012 nebo VS 2012 Express for Web, nainstaluje ho automaticky sada Windows Azure SDK. Visual Studio 2013 by mělo fungovat, ale kurz nebyl testován s ním a některé výběry nabídek a dialogových oken se liší. Pro nasazení Windows Azure je vyžadována verze sady Windows Azure SDK sady VS 2013 .
.NET 4.5 Většina uvedených funkcí bude fungovat v .NET 4, ale některé ne. Například podpora výčtu v EF vyžaduje .NET 4.5.
Entity Framework 5
Windows Azure SDK 2.1 Pokud přeskočíte kroky nasazení Windows Azure, sadu SDK nepotřebujete. Po vydání nové verze sady SDK se pomocí odkazu nainstaluje novější verze. V takovém případě možná budete muset některé pokyny přizpůsobit novému uživatelskému rozhraní a funkcím.

Dotazy

Pokud máte dotazy, které přímo nesouvisejí s kurzem, můžete je publikovat na fóru ASP.NET Entity Framework, na fóru Entity Framework a LINQ to Entities nebo StackOverflow.com.

Poděkování

Projděte si poslední kurz této série, kde najdete potvrzení a poznámku k VB.

Webová aplikace Contoso University

Aplikace, kterou budete v těchto kurzech vytvářet, je jednoduchý univerzitní web.

Uživatelé můžou zobrazit a aktualizovat informace o studentech, kurzech a instruktorech. Tady je několik obrazovek, které vytvoříte.

Students_Index_page

Snímky obrazovky, které zobrazují stránku hledání Studentů ukázkové webové aplikace Contoso University a stránku Vytvořit nového studenta

Styl uživatelského rozhraní tohoto webu byl udržován v blízkosti toho, co je generováno předdefinovanými šablonami, takže se kurz může zaměřit hlavně na to, jak používat Entity Framework.

Požadavky

Pokyny a snímky obrazovek v tomto kurzu předpokládají, že používáte Visual Studio 2012 nebo Visual Studio 2012 Express for Web s nejnovější aktualizací a sadou Azure SDK pro .NET nainstalovanou k červenci 2013. Všechny tyto informace získáte pomocí následujícího odkazu:

Azure SDK pro .NET (Visual Studio 2012)

Pokud máte nainstalovanou sadu Visual Studio, výše uvedený odkaz nainstaluje všechny chybějící komponenty. Pokud sadu Visual Studio nemáte, pomocí odkazu se nainstaluje Visual Studio 2012 Express for Web. Můžete použít Visual Studio 2013, ale některé požadované postupy a obrazovky se budou lišit.

Vytvoření webové aplikace MVC

Otevřete Visual Studio a pomocí šablony webové aplikace ASP.NET MVC 4 vytvořte nový projekt jazyka C# s názvem ContosoUniversity. Ujistěte se, že cílíte na rozhraní .NET Framework 4.5 (budete používat enum vlastnosti, které vyžadují rozhraní .NET 4.5).

New_project_dialog_box

V dialogovém okně Nový projekt ASP.NET MVC 4 vyberte šablonu Internetová aplikace .

Ponechte vybraný modul zobrazení Razor a políčko Create a unit test (Vytvořit projekt testu jednotek ) ponechte nezaškrtnuté.

Klikněte na OK.

Project_template_options

Nastavení stylu webu

Po několika jednoduchých změnách se nastaví nabídka webu, rozložení a domovská stránka.

Otevřete Views\Shared\_Layout.cshtml a nahraďte obsah souboru následujícím kódem. Změny jsou zvýrazněné.

<!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>

Tento kód provede následující změny:

  • Nahradí instance šablon "My ASP.NET MVC Application" a "your logo here" za "Contoso University".
  • Přidá několik odkazů na akce, které se použijí později v tomto kurzu.

V souboru Views\Home\Index.cshtml nahraďte obsah souboru následujícím kódem, abyste odstranili odstavce šablony týkající se ASP.NET a MVC:

@{
    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>
}

V části Controllers\HomeController.cs změňte hodnotu pro ViewBag.Message v Index metodě Action na "Welcome to Contoso University!", jak je znázorněno v následujícím příkladu:

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

    return View();
}

Stisknutím kombinace kláves CTRL+F5 spusťte web. Zobrazí se domovská stránka s hlavní nabídkou.

Contoso_University_home_page

Vytvoření datového modelu

Dále vytvoříte třídy entit pro aplikaci Contoso University. Začnete s následujícími třemi entitami:

Class_diagram

Mezi entitami a Enrollment existuje vztah Student 1:N a mezi entitami a Enrollment existuje vztah Course 1:N. Jinými slovy, student může být zaregistrovaný v libovolném počtu kurzů a v kurzu může být zaregistrovaný libovolný počet studentů.

V následujících částech vytvoříte třídu pro každou z těchto entit.

Poznámka

Pokud se před vytvořením všech těchto tříd entit pokusíte projekt zkompilovat, zobrazí se chyby kompilátoru.

Entita Student

Student_entity

Ve složce Models (Modely ) vytvořte Student.cs a nahraďte existující kód následujícím kódem:

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; }
    }
}

Vlastnost StudentID se stane sloupcem primárního klíče databázové tabulky, která odpovídá této třídě. Ve výchozím nastavení Entity Framework interpretuje vlastnost s názvem ID nebo classnameID jako primární klíč.

Vlastnost Enrollments je navigační vlastnost. Navigační vlastnosti obsahují další entity, které s touto entitou souvisejí. V tomto případě Enrollments bude vlastnost entity obsahovat všechny entity, které s touto Student entitou StudentEnrollment souvisejí. Jinými slovy, pokud má daný Student řádek v databázi dva související Enrollment řádky (řádky, které obsahují hodnotu primárního klíče daného studenta ve StudentID sloupci cizího klíče), Student bude navigační vlastnost dané entity Enrollments obsahovat tyto dvě Enrollment entity.

Navigační vlastnosti jsou obvykle definovány tak virtual , aby mohly využívat určité funkce Entity Framework, jako je opožděné načítání. (Opožděné načítání bude vysvětleno později v kurzu Čtení souvisejících dat dále v této sérii.

Pokud navigační vlastnost může obsahovat více entit (například v relacích M:N nebo 1:N), musí být jejím typem seznam, ve kterém lze přidávat, odstraňovat a aktualizovat položky, například ICollection.

Entita registrace

Enrollment_entity

Ve složce Models (Modely ) vytvořte Enrollment.cs a nahraďte stávající kód následujícím kódem:

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; }
    }
}

Vlastnost Grade je výčet. Otazník za Grade deklarací typu označuje, že Grade vlastnost je null. Známka, která má hodnotu null, se liší od nulové známky – null znamená, že známka není známa nebo ještě nebyla přiřazena.

Vlastnost StudentID je cizí klíč a odpovídající navigační vlastnost je Student. Entita Enrollment je přidružená k jedné Student entitě, takže vlastnost může obsahovat pouze jednu Student entitu (na rozdíl od Student.Enrollments navigační vlastnosti, kterou jste viděli dříve, která může obsahovat více Enrollment entit).

Vlastnost CourseID je cizí klíč a odpovídající navigační vlastnost je Course. Entita Enrollment je přidružená k jedné Course entitě.

Entita kurzu

Course_entity

Ve složce Modely vytvořte Course.cs a nahraďte stávající kód následujícím kódem:

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; }
    }
}

Vlastnost Enrollments je navigační vlastnost. Entita Course může souviset s libovolným počtem Enrollment entit.

Řekneme si další informace o [DatabaseGenerated(DatabaseGeneratedOption. None)] atribut v dalším kurzu. Tento atribut v podstatě umožňuje zadat primární klíč pro kurz místo toho, aby ho vygenerovala databáze.

Vytvoření kontextu databáze

Hlavní třída, která koordinuje funkce Entity Framework pro daný datový model, je kontextová třída databáze . Tuto třídu vytvoříte odvozením z třídy System.Data.Entity.DbContext . V kódu určíte, které entity jsou součástí datového modelu. Můžete také přizpůsobit určité chování entity frameworku. V tomto projektu má třída název SchoolContext.

Vytvořte složku s názvem DAL (pro vrstvu přístupu k datům). V této složce vytvořte nový soubor třídy s názvem SchoolContext.cs a nahraďte stávající kód následujícím kódem:

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>();
        }
    }
}

Tento kód vytvoří vlastnost DbSet pro každou sadu entit. V terminologii Entity Framework sada entit obvykle odpovídá databázové tabulce a entita odpovídá řádku v tabulce.

Příkaz modelBuilder.Conventions.Remove v metodě OnModelCreating brání v pluralizaci názvů tabulek. Pokud jste to neudělali, vygenerované tabulky by se jmenovaly Students, Coursesa Enrollments. Místo toho budou Studentnázvy tabulek , Coursea Enrollment. Vývojáři nesouhlasí s tím, jestli mají být názvy tabulek v množném čísle nebo ne. V tomto kurzu se používá jednotný formulář, ale důležité je, že můžete vybrat ten, který dáváte přednost zahrnutím nebo vynecháním tohoto řádku kódu.

SQL Server Express LocalDB

LocalDB je odlehčená verze databázového stroje SQL Server Express, která se spouští na vyžádání a běží v uživatelském režimu. LocalDB běží ve speciálním režimu spouštění SQL Server Express, který umožňuje pracovat s databázemi jako .mdf soubory. Soubory databáze LocalDB se obvykle uchovávají ve složce App_Data webového projektu. Funkce instance uživatele v SQL Server Express také umožňuje pracovat se soubory .mdf, ale funkce instance uživatele je zastaralá. Proto se pro práci se soubory .mdf doporučuje LocalDB.

SQL Server Express se obvykle nepoužívá pro produkční webové aplikace. Zejména LocalDB se nedoporučuje používat v produkčním prostředí s webovou aplikací, protože není navržená pro práci se službou IIS.

V sadě Visual Studio 2012 a novějších verzích se localDB instaluje ve výchozím nastavení se sadou Visual Studio. V sadě Visual Studio 2010 a starších verzích se SQL Server Express (bez LocalDB) instaluje ve výchozím nastavení se sadou Visual Studio. Pokud používáte Visual Studio 2010, musíte ji nainstalovat ručně.

V tomto kurzu budete pracovat s LocalDB, aby bylo možné databázi uložit do složky App_Data jako .mdf soubor. Otevřete kořenový souborWeb.config a přidejte do connectionStrings kolekce nový připojovací řetězec, jak je znázorněno v následujícím příkladu. (Nezapomeňte aktualizovat souborWeb.config v kořenové složce projektu. V podsložce Views je také Web.config soubor, který nemusíte aktualizovat.)

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

Ve výchozím nastavení Entity Framework hledá připojovací řetězec s názvem stejná jako DbContext třída (SchoolContextpro tento projekt). Přidaná připojovací řetězec určuje databázi LocalDB s názvem ContosoUniversity.mdf umístěnou ve složce App_Data. Další informace najdete v tématu SQL Server připojovací řetězce pro webové aplikace ASP.NET.

Ve skutečnosti nemusíte zadávat připojovací řetězec. Pokud nezadáte připojovací řetězec, Entity Framework ho pro vás vytvoří, ale databáze nemusí být ve složce App_data vaší aplikace. Informace o tom, kde bude databáze vytvořena, najdete v tématu Code First to a New Database.

Kolekce connectionStrings má také připojovací řetězec s názvemDefaultConnection, který se používá pro databázi členství. V tomto kurzu nebudete používat databázi členství. Jediným rozdílem mezi těmito dvěma připojovacími řetězci je název databáze a hodnota atributu name.

Nastavení a spuštění migrace Code First

Když poprvé začnete vyvíjet aplikaci, datový model se často mění a pokaždé, když se model změní, přestane být synchronizovaný s databází. Entity Framework můžete nakonfigurovat tak, aby automaticky vyřadil a znovu vytvořil databázi při každé změně datového modelu. To není problém v rané fázi vývoje, protože testovací data se snadno znovu vytvoří, ale po nasazení do produkčního prostředí obvykle chcete aktualizovat schéma databáze bez vyřazení databáze. Funkce Migrace umožňuje službě Code First aktualizovat databázi bez vyřazení a opětovného vytvoření. Na začátku vývojového cyklu nového projektu můžete použít DropCreateDatabaseIfModelChanges k odstranění, opětovnému vytvoření a opětovnému nasazení databáze při každé změně modelu. Když se připravíte na nasazení aplikace, můžete ji převést na přístup k migraci. V tomto kurzu budete používat jenom migrace. Další informace najdete v tématu Migrace Code First a Migrations Screencast Series.

Povolit Migrace Code First

  1. V nabídce Nástroje klikněte na Správce balíčků NuGet a pak na Konzola Správce balíčků.

    Selecting_Package_Manager_Console

  2. Na příkazovém PM> řádku zadejte následující příkaz:

    enable-migrations -contexttypename SchoolContext
    

    příkaz enable-migrations

    Tento příkaz vytvoří složku Migrations v projektu ContosoUniversity a vloží do ní Configuration.cs soubor, který můžete upravit a nakonfigurovat migrace.

    Složka Migrations

    Třída Configuration obsahuje metodu Seed , která je volána při vytvoření databáze a při každé aktualizaci po změně datového modelu.

    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" }
            //    );
            //
        }
    }
    

    Účelem této Seed metody je umožnit vložení testovacích dat do databáze poté, co ji Code First vytvoří nebo aktualizuje.

Nastavení metody Seed

Metoda Seed se spustí, když Migrace Code First vytvoří databázi a pokaždé, když aktualizuje databázi na nejnovější migraci. Účelem metody Seed je umožnit vložení dat do tabulek před prvním přístupem aplikace k databázi.

V dřívějších verzích Code First bylo před vydáním migrací běžné Seed , že metody vkládaly testovací data, protože při každé změně modelu během vývoje bylo nutné databázi zcela odstranit a znovu vytvořit od začátku. U Migrace Code First se testovací data uchovávají po změnách databáze, takže zahrnutí testovacích dat do metody Seed obvykle není nutné. Ve skutečnosti nechcete Seed , aby metoda vkláněla testovací data, pokud budete k nasazení databáze do produkčního prostředí používat migrace, protože metoda se spustí v produkčním Seed prostředí. V takovém případě chcete Seed , aby metoda vkláněla do databáze pouze data, která chcete vložit do produkčního prostředí. Můžete například chtít, aby databáze obsahovala skutečné názvy oddělení v Department tabulce, když bude aplikace k dispozici v produkčním prostředí.

V tomto kurzu budete používat migrace pro nasazení, ale vaše Seed metoda přesto vloží testovací data, aby bylo snazší zjistit, jak funkce aplikace fungují, aniž byste museli ručně vkládat velké množství dat.

  1. Obsah souboru Configuration.cs nahraďte následujícím kódem, který načte testovací data do nové databáze.

    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();
          }
       }
    }
    

    Metoda Seed přebírá objekt kontextu databáze jako vstupní parametr a kód v metodě používá tento objekt k přidání nových entit do databáze. Pro každý typ entity kód vytvoří kolekci nových entit, přidá je do příslušné vlastnosti DbSet a pak uloží změny do databáze. Není nutné volat saveChanges metodu po každé skupině entit, jak je to tady, ale to vám pomůže najít zdroj problému, pokud dojde k výjimce, když kód zapisuje do databáze.

    Některé příkazy, které vkládají data, používají Metodu AddOrUpdate k provedení operace "upsert". Vzhledem k tomu, že metoda Seed běží s každou migrací, nemůžete jenom vkládat data, protože řádky, které se pokoušíte přidat, už tam budou po první migraci, která vytvoří databázi. Operace upsert zabraňuje chybám, ke kterým by došlo při pokusu o vložení řádku, který již existuje, ale přepíše všechny změny dat, které jste mohli provést při testování aplikace. U testovacích dat v některých tabulkách to nemusí být vhodné: v některých případech při změně dat během testování chcete, aby změny zůstaly i po aktualizaci databáze. V takovém případě chcete provést operaci podmíněného vložení: vložte řádek jenom v případě, že ještě neexistuje. Metoda Seed používá oba přístupy.

    První parametr předaný AddOrUpdate metoda určuje vlastnost, která se má použít ke kontrole, jestli řádek již existuje. Pro data testovacího studenta, která zadáte, je možné k tomuto účelu LastName použít vlastnost, protože každé příjmení v seznamu je jedinečné:

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

    Tento kód předpokládá, že příjmení jsou jedinečná. Pokud ručně přidáte studenta s duplicitním příjmením, při příštím provedení migrace se zobrazí následující výjimka.

    Sequence obsahuje více než jeden prvek.

    Další informace o metodě najdete v AddOrUpdate tématu Péče o metodu ADDOrUpdate EF 4.3 na blogu Julie Lerman.

    Kód, který přidává Enrollment entity, nepoužívá metodu AddOrUpdate . Zkontroluje, jestli entita již existuje, a pokud entita neexistuje, vloží ji. Tento přístup zachová změny, které provedete ve třídě registrace při spuštění migrace. Kód prochází jednotlivými členy Enrollmentseznamu , a pokud se registrace v databázi nenajde, přidá ji do databáze. Při první aktualizaci databáze bude databáze prázdná, takže přidá každou registraci.

    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);
        }
    }
    

    Informace o tom, jak ladit metodu Seed a jak zpracovávat redundantní data, jako jsou například dva studenti s názvem Alexander Carson, najdete v tématu Seeding and Debugging Entity Framework (EF) DATABÁZE na blogu Ricka Andersona.

  2. Sestavte projekt.

Vytvoření a spuštění první migrace

  1. V okně konzoly Správce balíčků zadejte následující příkazy:

    add-migration InitialCreate
    update-database
    

    Snímek obrazovky s oknem konzoly Správce balíčků Příkazy přidání podtržítka migrace spojovníků počáteční vytvoření a aktualizace databáze spojovníků jsou zvýrazněné.

    Příkaz add-migration přidá do složky Migrations soubor [DateStamp]_InitialCreate.cs obsahující kód, který vytvoří databázi. První parametr (InitialCreate) se používá jako název souboru a může být libovolný. Obvykle zvolíte slovo nebo frázi, které shrnují, co se při migraci dělá. Pozdější migraci můžete například pojmenovat AddDepartmentTable.

    Složka Migrations s počáteční migrací

    Metoda UpInitialCreate třídy vytvoří databázové tabulky, které odpovídají sadám entit datového Down modelu, a metoda je odstraní. Migrace volá metodu Up , která implementuje změny datového modelu pro migraci. Když zadáte příkaz pro vrácení aktualizace zpět, Migrations zavolá metodu Down . Následující kód ukazuje obsah InitialCreate souboru:

    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");
            }
        }
    }
    

    Příkaz update-database spustí metodu Up pro vytvoření databáze a pak spustí metodu Seed pro naplnění databáze.

Pro váš datový model se teď vytvořila databáze SQL Server. Název databáze je ContosoUniversity a soubor .mdf je ve složce App_Data vašeho projektu, protože jste ho zadali v připojovací řetězec.

K zobrazení databáze v sadě Visual Studio můžete použít Průzkumníka serveru nebo SQL Server Průzkumník objektů (SSOX). Pro účely tohoto kurzu použijete Průzkumník serveru. V Visual Studio Express 2012 pro web se Průzkumník serveru nazývá Průzkumník databáze.

  1. V nabídce Zobrazení klikněte na Průzkumník serveru.

  2. Klikněte na ikonu Přidat připojení .

    Snímek obrazovky s oknem Průzkumníka databáze Ikona Přidat připojení je zvýrazněná.

  3. Pokud se zobrazí výzva v dialogovém okně Zvolit zdroj dat, klikněte na Microsoft SQL Server a potom klikněte na Pokračovat.

    Snímek obrazovky s dialogovým oknem Zvolit zdroj dat Je vybraný zdroj dat Microsoft S Q L Server.

  4. V dialogovém okně Přidat připojení jako Název serveru zadejte (localdb)\v11.0. V části Vyberte nebo zadejte název databáze vyberte ContosoUniversity.

    Snímek obrazovky s dialogovým oknem Přidat připojení Ukázkový název serveru a databáze Contoso University jsou zvýrazněné.

  5. Klikněte na OK.

  6. Rozbalte SchoolContext a pak rozbalte Tabulky.

    Snímek obrazovky se stránkou Průzkumník serveru Rozbalené jsou karty Kontext školy a Tabulky.

  7. Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit data tabulky zobrazte vytvořené sloupce a řádky vložené do tabulky.

    Tabulka Student

Vytvoření kontroleru studenta a zobrazení

Dalším krokem je vytvoření kontroleru a zobrazení ASP.NET MVC ve vaší aplikaci, které mohou pracovat s některou z těchto tabulek.

  1. Pokud chcete vytvořit Student kontroler, klikněte pravým tlačítkem na složku Controllers v Průzkumník řešení, vyberte Přidat a potom klikněte na Kontroler. V dialogovém okně Přidat kontroler vyberte následující možnosti a klikněte na Přidat:

    • Název kontroleru: StudentController.

    • Šablona: Kontroler MVC s akcemi čtení/zápisu a zobrazeními pomocí Entity Frameworku

    • Třída modelu: Student (ContosoUniversity.Models). (Pokud tuto možnost v rozevíracím seznamu nevidíte, sestavte projekt a zkuste to znovu.)

    • Třída kontextu dat: SchoolContext (ContosoUniversity.Models).

    • Zobrazení: Razor (CSHTML). (Výchozí hodnota.)

      Add_Controller_dialog_box_for_Student_controller

  2. Visual Studio otevře soubor Controllers\StudentController.cs . Uvidíte, že se vytvořila proměnná třídy, která vytvoří instanci objektu kontextu databáze:

    private SchoolContext db = new SchoolContext();
    

    Metoda Index action získá seznam studentů z entity Studenti nastavenou tak, že Students přečte vlastnost instance kontextu databáze:

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

    Zobrazení Student\Index.cshtml zobrazí tento seznam v tabulce:

    <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. Stisknutím kombinace kláves CTRL+F5 spusťte projekt.

    Kliknutím na kartu Studenti zobrazíte testovací data vložená metodou Seed .

    Stránka indexu studenta

Konvence

Množství kódu, který jste museli napsat, aby Entity Framework mohla vytvořit kompletní databázi za vás, je minimální z důvodu použití konvencí nebo předpokladů, které Entity Framework vytváří. Některé z nich již byly zaznamenány:

  • Jako názvy tabulek se používají pluralizované formy názvů tříd entit.
  • Názvy vlastností entit se používají pro názvy sloupců.
  • Vlastnosti entity s názvem ID nebo classnameID jsou rozpoznány jako vlastnosti primárního klíče.

Viděli jste, že konvence je možné přepsat (například jste určili, že názvy tabulek se nemají množně používat) a další informace o konvencích a jejich přepsání se dozvíte v kurzu Vytvoření složitějšího datového modelu v další části této série. Další informace najdete v tématu Code First Conventions.

Souhrn

Právě jste vytvořili jednoduchou aplikaci, která k ukládání a zobrazení dat používá Entity Framework a SQL Server Express. V následujícím kurzu se dozvíte, jak provádět základní operace CRUD (vytvoření, čtení, aktualizace a odstranění). Svůj názor můžete zanechat v dolní části této stránky. Dejte nám vědět, jak se vám tato část kurzu líbila a jak ji můžeme vylepšit.

Odkazy na další prostředky Entity Framework najdete v mapě obsahu ASP.NET Data Access.