Začínáme s Entity Framework 4.0 Database First a ASP.NET 4 Web Forms – část 5
Ukázková webová aplikace Contoso University ukazuje, jak vytvářet ASP.NET Web Forms aplikace pomocí entity frameworku 4.0 a sady Visual Studio 2010. Informace o sérii kurzů najdete v prvním kurzu v této řadě.
Práce se souvisejícími daty, pokračování
V předchozím kurzu jste začali používat EntityDataSource
ovládací prvek k práci se souvisejícími daty. Ve vlastnostech navigace jste zobrazili několik úrovní hierarchie a upravili jste data. V tomto kurzu budete pokračovat v práci se souvisejícími daty přidáním a odstraněním relací a přidáním nové entity, která má relaci k existující entitě.
Vytvoříte stránku, která přidá kurzy přiřazené k oddělením. Oddělení už existují, a když vytvoříte nový kurz, současně vytvoříte vztah mezi ním a existujícím oddělením.
Vytvoříte také stránku, která funguje se vztahem M:N tím, že přiřadíte instruktora ke kurzu (přidáte relaci mezi dvěma entitami, které vyberete) nebo odeberete instruktora z kurzu (odeberete relaci mezi dvěma entitami, které vyberete). Přidání relace mezi instruktorem a kurzem v databázi způsobí přidání nového řádku do CourseInstructor
asociační tabulky. Odebrání relace zahrnuje odstranění řádku z CourseInstructor
asociační tabulky. Provedete to však v Entity Frameworku nastavením navigačních vlastností bez explicitního odkazu na CourseInstructor
tabulku.
Přidání entity s relací k existující entitě
Vytvořte novou webovou stránku s názvem CoursesAdd.aspx , která používá stránku předlohy Site.Master , a přidejte do Content
ovládacího prvku s názvem Content2
následující kód :
<h2>Add Courses</h2>
<asp:EntityDataSource ID="CoursesEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="Courses"
EnableInsert="True" EnableDelete="True" >
</asp:EntityDataSource>
<asp:DetailsView ID="CoursesDetailsView" runat="server" AutoGenerateRows="False"
DataSourceID="CoursesEntityDataSource" DataKeyNames="CourseID"
DefaultMode="Insert" oniteminserting="CoursesDetailsView_ItemInserting">
<Fields>
<asp:BoundField DataField="CourseID" HeaderText="ID" />
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Credits" HeaderText="Credits" />
<asp:TemplateField HeaderText="Department">
<InsertItemTemplate>
<asp:EntityDataSource ID="DepartmentsEntityDataSource" runat="server" ConnectionString="name=SchoolEntities"
DefaultContainerName="SchoolEntities" EnableDelete="True" EnableFlattening="False"
EntitySetName="Departments" EntityTypeFilter="Department">
</asp:EntityDataSource>
<asp:DropDownList ID="DepartmentsDropDownList" runat="server" DataSourceID="DepartmentsEntityDataSource"
DataTextField="Name" DataValueField="DepartmentID"
oninit="DepartmentsDropDownList_Init">
</asp:DropDownList>
</InsertItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
Tato značka vytvoří ovládací prvek EntityDataSource
, který vybere kurzy, který umožňuje vkládání a který určuje obslužnou rutinu Inserting
události. Obslužnou rutinu použijete k aktualizaci Department
navigační vlastnosti při vytvoření nové Course
entity.
Značka také vytvoří ovládací prvek, který DetailsView
se použije pro přidávání nových Course
entit. Značky používají pro Course
vlastnosti entity svázaná pole. Musíte zadat hodnotu, CourseID
protože se nejedná o pole ID generované systémem. Místo toho se jedná o číslo kurzu, které se musí při vytvoření kurzu zadat ručně.
Pro vlastnost navigace použijete pole Department
šablony, protože vlastnosti navigace nelze použít s ovládacími BoundField
prvky. Pole šablony obsahuje rozevírací seznam pro výběr oddělení. Rozevírací seznam je vázán na Departments
sadu entit pomocí namísto Eval
Bind
, protože nelze přímo svázat navigační vlastnosti, abyste je mohli aktualizovat. Zadáte obslužnou rutinu DropDownList
pro událost ovládacího prvku Init
, abyste mohli uložit odkaz na ovládací prvek pro použití kódem, který aktualizuje DepartmentID
cizí klíč.
V souboru CoursesAdd.aspx.cs těsně za deklaraci částečné třídy přidejte pole třídy, které bude obsahovat odkaz na DepartmentsDropDownList
ovládací prvek:
private DropDownList departmentDropDownList;
Přidejte obslužnou rutinu DepartmentsDropDownList
pro událost ovládacího prvku Init
, abyste mohli uložit odkaz na ovládací prvek. To vám umožní získat hodnotu, kterou uživatel zadal, a použít ji k aktualizaci DepartmentID
hodnoty Course
entity.
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
departmentDropDownList = sender as DropDownList;
}
Přidejte obslužnou rutinu DetailsView
pro událost ovládacího prvku Inserting
:
protected void CoursesDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
var departmentID = Convert.ToInt32(departmentDropDownList.SelectedValue);
e.Values["DepartmentID"] = departmentID;
}
Když uživatel klikne na Insert
, Inserting
událost se vyvolá před vložením nového záznamu. Kód v obslužné rutině získá DepartmentID
z DropDownList
ovládacího prvku a použije ho k nastavení hodnoty, která se použije pro DepartmentID
vlastnost Course
entity.
Entity Framework se postará o přidání tohoto kurzu do Courses
vlastnosti navigace přidružené Department
entity. Také přidá oddělení do Department
vlastnosti Course
navigace entity.
Spusťte stránku.
Zadejte ID, titul, počet kreditů, vyberte oddělení a klikněte na Vložit.
Spusťte stránku Courses.aspx a vyberte stejné oddělení, abyste viděli nový kurz.
Práce s relacemi M:N
Relace mezi Courses
sadou entit a People
sadou entit je relace M:N. Entita Course
má navigační vlastnost s názvem People
, která může obsahovat nula, jednu nebo více souvisejících Person
entit (představující instruktory přiřazené k výuce daného kurzu). Entita Person
má navigační vlastnost s názvem Courses
, která může obsahovat nula, jednu nebo více souvisejících Course
entit (což představuje kurzy, které má instruktor přiřazený k výuce). Jeden instruktor může vyučovat více kurzů a jeden kurz může vyučovat více instruktorů. V této části návodu přidáte a odeberete relace mezi Person
entitami a Course
aktualizací navigačních vlastností souvisejících entit.
Vytvořte novou webovou stránku s názvem InstructorsCourses.aspx , která používá stránku předlohy Site.Master , a přidejte do Content
ovládacího prvku s názvem Content2
následující kód :
<h2>Assign Instructors to Courses or Remove from Courses</h2>
<br />
<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Where="it.HireDate is not null" Select="it.LastName + ', ' + it.FirstMidName AS Name, it.PersonID">
</asp:EntityDataSource>
Select an Instructor:
<asp:DropDownList ID="InstructorsDropDownList" runat="server" DataSourceID="InstructorsEntityDataSource"
AutoPostBack="true" DataTextField="Name" DataValueField="PersonID"
OnSelectedIndexChanged="InstructorsDropDownList_SelectedIndexChanged"
OnDataBound="InstructorsDropDownList_DataBound">
</asp:DropDownList>
<h3>
Assign a Course</h3>
<br />
Select a Course:
<asp:DropDownList ID="UnassignedCoursesDropDownList" runat="server"
DataTextField="Title" DataValueField="CourseID">
</asp:DropDownList>
<br />
<asp:Button ID="AssignCourseButton" runat="server" Text="Assign" OnClick="AssignCourseButton_Click" />
<br />
<asp:Label ID="CourseAssignedLabel" runat="server" Visible="false" Text="Assignment successful"></asp:Label>
<br />
<h3>
Remove a Course</h3>
<br />
Select a Course:
<asp:DropDownList ID="AssignedCoursesDropDownList" runat="server"
DataTextField="title" DataValueField="courseiD">
</asp:DropDownList>
<br />
<asp:Button ID="RemoveCourseButton" runat="server" Text="Remove" OnClick="RemoveCourseButton_Click" />
<br />
<asp:Label ID="CourseRemovedLabel" runat="server" Visible="false" Text="Removal successful"></asp:Label>
Tato značka vytvoří ovládací prvekEntityDataSource
, který načte název a Person
PersonID
entity pro instruktory. Ovládací DropDrownList
prvek je vázán na EntityDataSource
ovládací prvek. Ovládací DropDownList
prvek určuje obslužnou rutinu DataBound
události. Tuto obslužnou rutinu použijete k vytvoření vazby dvou rozevíracích seznamů, které zobrazují kurzy.
Přirážka také vytvoří následující skupinu ovládacích prvků, které se použijí pro přiřazení kurzu vybranému instruktoru:
- Ovládací
DropDownList
prvek pro výběr kurzu, který chcete přiřadit. Tento ovládací prvek bude naplněn kurzy, které aktuálně nejsou přiřazeny vybranému instruktorovi. - Ovládací
Button
prvek pro zahájení přiřazení. - Ovládací
Label
prvek, který zobrazí chybovou zprávu, pokud přiřazení selže.
Nakonec přirážka vytvoří také skupinu ovládacích prvků, které se použijí k odebrání kurzu vybranému instruktoru.
V části InstructorsCourses.aspx.cs přidejte příkaz using:
using ContosoUniversity.DAL;
Přidejte metodu pro naplnění dvou rozevíracích seznamů, které zobrazují kurzy:
private void PopulateDropDownLists()
{
using (var context = new SchoolEntities())
{
var allCourses = (from c in context.Courses
select c).ToList();
var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
var instructor = (from p in context.People.Include("Courses")
where p.PersonID == instructorID
select p).First();
var assignedCourses = instructor.Courses.ToList();
var unassignedCourses = allCourses.Except(assignedCourses.AsEnumerable()).ToList();
UnassignedCoursesDropDownList.DataSource = unassignedCourses;
UnassignedCoursesDropDownList.DataBind();
UnassignedCoursesDropDownList.Visible = true;
AssignedCoursesDropDownList.DataSource = assignedCourses;
AssignedCoursesDropDownList.DataBind();
AssignedCoursesDropDownList.Visible = true;
}
}
Tento kód získá všechny kurzy ze Courses
sady entit a kurzy získá z Courses
navigační vlastnosti Person
entity pro vybraného instruktora. Pak určí, které kurzy budou přiřazeny danému instruktorovi, a odpovídajícím způsobem naplní rozevírací seznamy.
Přidejte obslužnou rutinu Assign
pro událost tlačítka Click
:
protected void AssignCourseButton_Click(object sender, EventArgs e)
{
using (var context = new SchoolEntities())
{
var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
var instructor = (from p in context.People
where p.PersonID == instructorID
select p).First();
var courseID = Convert.ToInt32(UnassignedCoursesDropDownList.SelectedValue);
var course = (from c in context.Courses
where c.CourseID == courseID
select c).First();
instructor.Courses.Add(course);
try
{
context.SaveChanges();
PopulateDropDownLists();
CourseAssignedLabel.Text = "Assignment successful.";
}
catch (Exception)
{
CourseAssignedLabel.Text = "Assignment unsuccessful.";
//Add code to log the error.
}
CourseAssignedLabel.Visible = true;
}
}
Tento kód získá entitu Person
pro vybraného instruktora, získá entitu Course
pro vybraný kurz a přidá vybraný kurz do Courses
vlastnosti navigace entity instruktora Person
. Pak uloží změny do databáze a znovu naplní rozevírací seznamy, aby se výsledky okamžitě zobrazily.
Přidejte obslužnou rutinu Remove
pro událost tlačítka Click
:
protected void RemoveCourseButton_Click(object sender, EventArgs e)
{
using (var context = new SchoolEntities())
{
var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
var instructor = (from p in context.People
where p.PersonID == instructorID
select p).First();
var courseID = Convert.ToInt32(AssignedCoursesDropDownList.SelectedValue);
var courses = instructor.Courses;
var courseToRemove = new Course();
foreach (Course c in courses)
{
if (c.CourseID == courseID)
{
courseToRemove = c;
break;
}
}
try
{
courses.Remove(courseToRemove);
context.SaveChanges();
PopulateDropDownLists();
CourseRemovedLabel.Text = "Removal successful.";
}
catch (Exception)
{
CourseRemovedLabel.Text = "Removal unsuccessful.";
//Add code to log the error.
}
CourseRemovedLabel.Visible = true;
}
}
Tento kód získá entitu Person
pro vybraného instruktora, získá entitu Course
pro vybraný kurz a odebere vybraný kurz z Person
vlastnosti navigace entity Courses
. Pak uloží změny do databáze a znovu naplní rozevírací seznamy, aby se výsledky okamžitě zobrazily.
Přidejte do Page_Load
metody kód, který zajistí, že chybové zprávy nejsou viditelné, pokud není k dispozici žádná chyba, která by se nahlásila, a přidejte obslužné rutiny pro DataBound
události a SelectedIndexChanged
rozevíracího seznamu instruktorů, které naplní rozevírací seznamy kurzů:
protected void Page_Load(object sender, EventArgs e)
{
CourseAssignedLabel.Visible = false;
CourseRemovedLabel.Visible = false;
}
protected void InstructorsDropDownList_DataBound(object sender, EventArgs e)
{
PopulateDropDownLists();
}
protected void InstructorsDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
PopulateDropDownLists();
}
Spusťte stránku.
Vyberte instruktora. V rozevíracím seznamu Přiřadit kurz se zobrazí kurzy, které instruktor nevyučuje, a v rozevíracím seznamu Odebrat kurz se zobrazí kurzy, ke kterým už je instruktor přiřazený. V části Přiřadit kurz vyberte kurz a klikněte na Přiřadit. Kurz se přesune do rozevíracího seznamu Odebrat kurz . Vyberte kurz v části Odebrat kurz a klikněte na Odebrat. Kurz se přesune do rozevíracího seznamu Přiřadit kurz .
Teď jste viděli několik dalších způsobů, jak pracovat se souvisejícími daty. V následujícím kurzu se dozvíte, jak pomocí dědičnosti v datovém modelu zlepšit udržovatelnost vaší aplikace.