Vytvoření datového modelu Entity Framework pro aplikaci ASP.NET MVC (1 z 10)
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.
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).
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.
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>© @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.
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:
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
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 Student
Enrollment
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
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
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
, 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. 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 (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 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
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í Configuration.cs soubor, který můžete upravit a nakonfigurovat migrace.
Třída
Configuration
obsahuje metoduSeed
, 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.
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á metoduAddOrUpdate
. 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 členyEnrollment
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 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.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á 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.Metoda
Up
InitialCreate
třídy vytvoří databázové tabulky, které odpovídají sadám entit datovéhoDown
modelu, a metoda je odstraní. Migrace volá metoduUp
, která implementuje změny datového modelu pro migraci. Když zadáte příkaz pro vrácení aktualizace zpět, Migrations zavolá 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 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.
V nabídce Zobrazení klikněte na Průzkumník serveru.
Klikněte na ikonu Přidat připojení .
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.
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.
Klikněte na OK.
Rozbalte SchoolContext a pak rozbalte Tabulky.
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.
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.
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.)
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, žeStudents
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> }
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 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.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro