Vytvoření datového modelu Entity Framework pro aplikaci ASP.NET MVC (1 z 10)
Tom Dykstra
Poznámka:
K dispozici je 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 Framework 5 a sady Visual Studio 2012. Ukázková aplikace je web fiktivní univerzity Contoso. Zahrnuje funkce, jako je přijetí studentů, vytváření kurzů a zadání instruktora. Tato série kurzů vysvětluje, jak sestavit ukázkovou aplikaci Contoso University.
Code First
Data 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 volbě nejvhodnější pro váš scénář najdete v tématu Pracovní postupy vývoje pro Entity Framework.
MVC
Ukázková aplikace je založená na ASP.NET MVC. Pokud chcete pracovat s modelem webových formulářů ASP.NET, podívejte se na řadu kurzů o vazbách modelu a webových formulářích a ASP.NET mapě obsahu Aplikace Data Access.
Verze softwaru
Zobrazeno v kurzu Funguje také s Windows 8 Windows 7 Visual Studio 2012 Visual Studio 2012 Express pro web Pokud ještě nemáte sadu VS 2012 nebo VS 2012 Express for Web, automaticky se nainstaluje sada Windows Azure SDK. Visual Studio 2013 by mělo fungovat, ale kurz s ním nebyl testován a některé výběry nabídek a dialogová okna se liší. Pro nasazení Windows Azure se vyžaduje verze sady Sdk sady VS 2013. .NET 4.5 Většina zobrazených funkcí bude fungovat v .NET 4, ale některé nebudou fungovat. 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, nepotřebujete sadu SDK. Po vydání nové verze sady SDK se na odkaz 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 nesouvisí s kurzem, můžete je publikovat na fóru ASP.NET Entity Framework, fóru Entity Framework a LINQ to Entities nebo StackOverflow.com.
Poděkování
Podívejte se na poslední kurz série, kde najdete potvrzení a poznámku o VB.
Webová aplikace Contoso University
Aplikace, kterou budete vytvářet v těchto kurzech, je jednoduchý web pro vysokoškoláky.
Uživatelé můžou zobrazit a aktualizovat informace o studentech, kurzech a instruktorech. Tady je několik obrazovek, které vytvoříte.
Styl uživatelského rozhraní tohoto webu byl udržován v blízkosti toho, co generuje předdefinované šablony, aby se kurz mohl zaměřit hlavně na použití Entity Frameworku.
Požadavky
Pokyny a snímky obrazovky v tomto kurzu předpokládají, že používáte Visual Studio 2012 nebo Visual Studio 2012 Express pro web s nejnovější aktualizací a sadou Azure SDK pro .NET nainstalovanou od července 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 visual Studio nemáte, odkaz nainstaluje Visual Studio 2012 Express pro web. Visual Studio 2013 můžete použít, ale některé požadované postupy a obrazovky se budou lišit.
Vytvoření webové aplikace MVC
Otevřete Visual Studio a vytvořte nový projekt C# s názvem ContosoUniversity pomocí šablony webové aplikace ASP.NET MVC 4. Ujistěte se, že cílíte na rozhraní .NET Framework 4.5 (budete používat enum
vlastnosti a které vyžadují .NET 4.5).
V dialogovém okně Nový ASP.NET projekt MVC 4 vyberte šablonu internetové aplikace .
Ponechte vybraný modul zobrazení Razor a nechejte zaškrtnuté políčko Vytvořit projekt testu jednotek.
Klikněte na OK.
Nastavení stylu webu
Několik jednoduchých změn nastaví nabídku webu, rozložení a domovskou stránku.
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>© @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 šablony "My ASP.NET MVC Application" (Moje ASP.NET aplikace MVC) a "vaše logo sem" na "Contoso University".
- Přidá několik odkazů akcí, které budou použity později v kurzu.
V views\Home\Index.cshtml nahraďte obsah souboru následujícím kódem, abyste vyloučili odstavce šablony o 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 controllers\HomeController.cs změňte hodnotu ViewBag.Message
v Index
metodě Akce 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 web spusťte. Zobrazí se domovská stránka s hlavní nabídkou.
Vytvoření datového modelu
V dalším kroku vytvoříte třídy entit pro aplikaci Contoso University. Začnete následujícími třemi entitami:
Mezi entitami existuje vztah Student
Enrollment
1:N a mezi entitami existuje vztah Course
Enrollment
1:N. Jinými slovy, student může být zapsán do libovolného počtu kurzů a kurz může mít v něm 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 studenta
Ve složce Models vytvořte Student.cs a nahraďte stávají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 v tabulce databáze, která odpovídá této třídě. Ve výchozím nastavení Entity Framework interpretuje vlastnost, která má název ID
nebo název ID
třídy jako primární klíč.
Vlastnost Enrollments
je navigační vlastnost. Vlastnosti navigace obsahují další entity, které souvisejí s touto entitou. V tomto případě Enrollments
bude vlastnost Student
entity obsahovat všechny Enrollment
entity, které souvisejí s danou Student
entitou. 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 studenta ve StudentID
sloupci cizího klíče), Student
bude tato vlastnost navigace entity Enrollments
obsahovat tyto dvě Enrollment
entity.
Vlastnosti navigace 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 části Kurz čtení souvisejících dat dále v této sérii.
Pokud navigační vlastnost může obsahovat více entit (jako v relacích M:N nebo 1:N), musí být jeho typ seznamem, ve kterém lze přidávat, odstraňovat a aktualizovat položky, například ICollection
.
Entita registrace
Ve složce Models 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ýčt. Otazník za Grade
deklaraci typu označuje, že Grade
vlastnost je nullable. Známka, která má hodnotu null, se liší od nulové známky – hodnota 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 tato vlastnost může obsahovat pouze jednu Student
entitu (na rozdíl od Student.Enrollments
vlastnosti navigace, kterou jste viděli dříve, což 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
Ve složce Models 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.
O funkci [DatabaseGenerated(DatabaseGeneratedOption) řekneme více. Žádný)] atribut v dalším kurzu. Tento atribut v podstatě umožňuje zadat primární klíč pro kurz, nikoli databázi vygenerovat.
Vytvoření kontextu databáze
Hlavní třída, která koordinuje funkce Entity Framework pro daný datový model, je třída kontextu databáze. Tuto třídu vytvoříte odvozením z System.Data.Entity.DbContext třídy. V kódu určíte, které entity jsou součástí datového modelu. Můžete také přizpůsobit určité chování entity Framework. 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 onModelCreating metoda zabraňuje názvům tabulek v množném čísle. Pokud byste to neudělali, vygenerované tabulky budou pojmenovány Students
, Courses
a Enrollments
. Místo toho budou Student
názvy tabulek , Course
a Enrollment
. Vývojáři nesouhlasí s tím, jestli mají být názvy tabulek v množném čísle nebo ne. Tento kurz používá jednotný tvar, ale důležitým bodem je, že můžete vybrat ten, který formulář dáváte přednost zahrnutím nebo vynecháním tohoto řádku kódu.
SQL Server Express LocalDB
LocalDB je zjednodušená verze databázového stroje SQL Server Express, která začíná na vyžádání a běží v uživatelském režimu. LocalDB běží ve speciálním režimu spouštění SQL Serveru Express, který umožňuje pracovat s databázemi jako se soubory .mdf . Soubory databáze LocalDB se obvykle uchovávají ve složce App_Data webového projektu. Funkce instance uživatele v SQL Serveru Express také umožňuje pracovat s .mdf soubory, ale funkce instance uživatele je zastaralá. Proto se doporučuje pracovat s .mdf soubory LocalDB.
Sql Server Express se obvykle nepoužívá pro produkční webové aplikace. Místní databáze se nedoporučuje pro produkční použití 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 ve výchozím nastavení nainstaluje LocalDB se sadou Visual Studio. V sadě Visual Studio 2010 a starších verzích je SQL Server Express (bez localDB) ve výchozím nastavení nainstalován se sadou Visual Studio; Pokud používáte Visual Studio 2010, musíte ho nainstalovat ručně.
V tomto kurzu budete pracovat s LocalDB, aby databáze byla uložena ve složce App_Data jako soubor .mdf . Otevřete kořenový soubor Web.config a přidejte do connectionStrings
kolekce nový připojovací řetězec, jak je znázorněno v následujícím příkladu. (Ujistěte se, že aktualizujete Soubor Web.config ve složce kořenového projektu. Soubor Web.config je také v podsložce Zobrazení, kterou 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 pojmenovanou stejnou jako DbContext
třída (SchoolContext
pro 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 naleznete v tématu Připojovací řetězce SYSTÉMU SQL Server pro ASP.NET webové aplikace.
Ve skutečnosti nemusíte zadávat připojovací řetězec. Pokud nezadáte připojovací řetězec, Entity Framework ji vytvoří za vás. Databáze ale nemusí být ve složce App_data vaší aplikace. Informace o tom, kde se databáze vytvoří, najdete v tématu Code First do nové databáze.
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í řetězec 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ž model změní, že se nesynchronizuje s databází. Rozhraní Entity Framework můžete nakonfigurovat tak, aby při každé změně datového modelu automaticky vyřazuje a znovu vytvořila databázi. 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í databáze. V rané fázi vývojového cyklu nového projektu můžete chtít použít DropCreateDatabaseIfModelChanges k vyřazení, opětovnému vytvoření a opětovnému vytvoření databáze při každé změně modelu. Jeden, který jste připraveni nasadit aplikaci, můžete převést na přístup k migracím. V tomto kurzu budete používat pouze migrace. Další informace najdete v tématu Migrace Code First a migrace řady screencastů.
Povolení Migrace Code First
V nabídce Nástroje klikněte na Správce balíčků NuGet a pak na Konzola Správce balíčků.
Na příkazovém
PM>
řádku zadejte následující příkaz:enable-migrations -contexttypename SchoolContext
Tento příkaz vytvoří složku Migrations v projektu ContosoUniversity a vloží do ní soubor Configuration.cs , který můžete upravit a nakonfigurovat migrace.
Třída
Configuration
obsahuje metoduSeed
, která je volána při vytvoření databáze a pokaždé, když se aktualizuje 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 po vytvoření nebo aktualizaci kódu First.
Nastavení počáteční metody
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ředtím, než aplikace poprvé přistupuje k databázi.
V dřívějších verzích Code First bylo před vydáním migrace běžné Seed
, že metody vkládání testovacích dat, protože při každé změně modelu během vývoje databáze bylo nutné zcela odstranit a znovu vytvořit úplně od začátku. Při 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ádala testovací data, pokud k nasazení databáze do produkčního prostředí použijete migrace, protože Seed
metoda se spustí v produkčním prostředí. V takovém případě chcete, Seed
aby metoda vložil 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 do tabulky skutečné názvy Department
oddělení, jakmile bude aplikace dostupná 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.
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(); } } }
Seed metoda 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é zavolat metodu SaveChanges po každé skupině entit, jak je zde provedeno, 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í AddOrUpdate metodu k provedení operace upsert. Vzhledem k tomu, že metoda
Seed
běží s každou migrací, nemůžete jenom vložit data, protože řádky, které se pokoušíte přidat, už budou existovat po první migraci, která vytvoří databázi. Operace upsert zabraňuje chybám, ke kterým by došlo, pokud se pokusíte vložit řádek, 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 možná nebudete chtít, aby k tomu došlo: v některých případech při změně dat při testování chcete, aby změny zůstaly po aktualizacích 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ý metodě AddOrUpdate určuje vlastnost, která se má použít ke kontrole, zda řádek již existuje. Pro údaje o testech studentů, které poskytujete, lze vlastnost použít k tomuto účelu,
LastName
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í migraci se zobrazí následující výjimka.
Sekvence obsahuje více než jeden prvek.
Další informace o
AddOrUpdate
metodě naleznete v tématu Péče o EF 4.3 AddOrUpdate Metoda na Blogu Julie Lermana.Kód, který přidává
Enrollment
entity, metoduAddOrUpdate
nepoužívá. Zkontroluje, jestli už entita existuje, a pokud entitu 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í každý členEnrollment
seznamu 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 dva studenti s názvem "Alexander Carson", naleznete v tématu Seeding a Ladění Databází Entity Framework (EF) na blogu Rick Andersona.Sestavte projekt.
Vytvoření a spuštění první migrace
V okně konzoly Správce balíčků zadejte následující příkazy:
add-migration InitialCreate update-database
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á pro název souboru a může být jakýkoliv, co chcete; obvykle zvolíte slovo nebo frázi, která shrnuje, co se provádí v migraci. Můžete například pojmenovat pozdější migraci AddDepartmentTable.Up
MetodaInitialCreate
třídy vytvoří databázové tabulky, které odpovídají sadám entit datového modelu, aDown
metoda je odstraní. Migrace volá metoduUp
pro implementaci změn datového modelu pro migraci. Když zadáte příkaz pro vrácení aktualizace zpět, migrace volá metoduDown
. Následující kód ukazuje obsahInitialCreate
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í metoduUp
pro vytvoření databáze a pak spustí metoduSeed
pro naplnění databáze.
Pro datový model se teď vytvořila databáze SQL Serveru. Název databáze je ContosoUniversity a soubor .mdf je ve složce App_Data projektu, protože jste 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). V tomto kurzu použijete Průzkumníka serveru. V sadě Visual Studio Express 2012 pro web se Průzkumník serveru nazývá Průzkumník databáze.
V nabídce Zobrazení klikněte na Průzkumníka serveru.
Klikněte na ikonu Přidat připojení .
Pokud se zobrazí výzva dialogové okno Zvolit zdroj dat, klepněte na položku Microsoft SQL Server a potom klepněte na tlačítko Pokračovat.
V dialogovém okně Přidat připojení zadejte (localdb)\v11.0 název serveru. V části Vybrat nebo zadat název databáze vyberte ContosoUniversity.
Klikněte na OK.
Rozbalte SchoolContext a potom rozbalte tabulky.
Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit data tabulky zobrazte sloupce vytvořené a řádky vložené do tabulky.
Vytvoření kontroleru a zobrazení studentů
Dalším krokem je vytvoření kontroleru ASP.NET MVC a zobrazení ve vaší aplikaci, které můžou pracovat s jednou z těchto tabulek.
Chcete-li vytvořit
Student
kontroler, klepněte pravým tlačítkem myši na složku Kontrolery v Průzkumník řešení, vyberte Přidat a klepněte na tlačítko Řadič. V dialogovém okně Přidat kontroler proveďte následující výběry a klepněte na tlačítko Přidat:Název kontroleru: StudentController.
Šablona: Kontroler MVC s akcemi čtení a 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.)
Visual Studio otevře soubor Controllers\StudentController.cs . Vidíte, že byla vytvořena proměnná třídy, která vytvoří instanci objektu kontextu databáze:
private SchoolContext db = new SchoolContext();
Metoda
Index
akce získá seznam studentů z entity Students nastavenou čtenímStudents
vlastnosti 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> }
Stisknutím kombinace kláves CTRL+F5 spusťte projekt.
Kliknutím na kartu Studenti zobrazíte testovací data vložená metodou
Seed
.
Konvence
Množství kódu, který jste museli napsat, aby Entity Framework mohl vytvořit úplnou databázi za vás, je minimální kvůli použití konvencí nebo předpokladů, které Entity Framework dělá. Některé z nich již byly zaznamenány:
- Tvary názvů tříd entit v množném čísle se používají jako názvy tabulek.
- Názvy vlastností entity se používají pro názvy sloupců.
- Vlastnosti entity s názvem
ID
nebo názvemID
třídy 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 by neměly být v množném čísle) a dozvíte se další informace o konvencích a o tom, jak je přepsat v kurzu Vytvoření složitějšího datového modelu později v této sérii. Další informace najdete v tématu Konvence Code First.
Shrnutí
Teď 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, odstranění). Svůj názor můžete zanechat v dolní části této stránky. Dejte nám prosí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 Accessu.