Použití Entity Framework 4.0 a ObjectDataSource Ovládací prvek, Část 1: Začínáme
Tato série kurzů vychází z webové aplikace Contoso University vytvořené Začínáme s řadou kurzů Entity Framework 4.0. Pokud jste nedokončí předchozí kurzy, můžete si jako výchozí bod pro tento kurz stáhnout aplikaci , kterou jste vytvořili. Můžete si také stáhnout aplikaci vytvořenou kompletní řadou kurzů.
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. Ukázková aplikace je web fiktivní univerzity Contoso. Zahrnuje funkce, jako je přijetí studentů, vytváření kurzů a zadání instruktora.
Tento kurz ukazuje příklady v jazyce C#. Ukázka ke stažení obsahuje kód v jazyce C# i Visual Basic.
První databáze
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 Database 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 Pracovní postupy vývoje entity frameworku.
webové formuláře
Stejně jako řada Začínáme i tato série kurzů používá model ASP.NET Web Forms a předpokládá, že víte, jak pracovat s ASP.NET Web Forms v sadě Visual Studio. Pokud ne, podívejte se na Začínáme s ASP.NET 4.5 Web Forms. Pokud dáváte přednost práci s architekturou ASP.NET MVC, projděte si téma Začínáme s rozhraním Entity Framework pomocí ASP.NET MVC.
Verze softwaru
Zobrazeno v kurzu Funguje také s Windows 7 Windows 8 Visual Studio 2010 Visual Studio 2010 Express pro web. Kurz nebyl testován s novějšími verzemi sady Visual Studio. Výběry nabídek, dialogová okna a šablony jsou různé. .NET 4 .NET 4.5 je zpětně kompatibilní s .NET 4, ale kurz nebyl testován s .NET 4.5. Entity Framework 4 Kurz nebyl testován s novějšími verzemi Entity Frameworku. Počínaje Entity Framework 5 používá EF ve výchozím nastavení ten DbContext API
, který byl zaveden s EF 4.1. Ovládací prvek EntityDataSource byl navržen tak, aby používalObjectContext
rozhraní API. Informace o použití ovládacího prvku EntityDataSource s rozhraním API najdete vDbContext
tomto blogovém příspěvku.Dotazy
Pokud máte otázky, 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 na StackOverflow.com.
Ovládací EntityDataSource
prvek umožňuje velmi rychle vytvořit aplikaci, ale obvykle vyžaduje, abyste na stránkách .aspx zachovali značné množství obchodní logiky a logiky přístupu k datům. Pokud očekáváte, že se vaše aplikace zvětšuje ve složitosti a bude vyžadovat průběžnou údržbu, můžete předem investovat více času na vývoj, abyste vytvořili vícevrstvé nebo vrstvené aplikační struktury, které budou lépe udržovatelné. K implementaci této architektury oddělíte prezentační vrstvu od vrstvy obchodní logiky (BLL) a vrstvy přístupu k datům (DAL). Jedním ze způsobů, jak tuto strukturu implementovat, je použít ObjectDataSource
ovládací prvek místo EntityDataSource
ovládacího prvku. Při použití ObjectDataSource
ovládacího prvku implementujete vlastní kód pro přístup k datům a pak ho vyvoláte na stránkách .aspx pomocí ovládacího prvku, který má mnoho stejných funkcí jako jiné ovládací prvky zdroje dat. To vám umožní zkombinovat výhody n-vrstvého přístupu s výhodami použití Web Forms řízení přístupu k datům.
Ovládací ObjectDataSource
prvek poskytuje větší flexibilitu i v jiných ohledech. Vzhledem k tomu, že píšete vlastní kód pro přístup k datům, je jednodušší udělat víc než jen číst, vkládat, aktualizovat nebo odstraňovat konkrétní typ entity, což jsou úlohy, ke kterým EntityDataSource
je ovládací prvek navržen. Můžete například provádět protokolování při každé aktualizaci entity, archivovat data při každém odstranění entity nebo automaticky kontrolovat a aktualizovat související data podle potřeby při vkládání řádku s hodnotou cizího klíče.
Třídy obchodní logiky a úložiště
Ovládací ObjectDataSource
prvek funguje tak, že vyvolá třídu, kterou vytvoříte. Třída zahrnuje metody, které načítají a aktualizují data, a názvy těchto metod zadáte ovládacímu ObjectDataSource
prvku ve značkách. Během vykreslování nebo zpětného ObjectDataSource
zpracování volá metody, které jste zadali.
Kromě základních operací CRUD může třída, kterou vytvoříte pro použití s ovládacím ObjectDataSource
prvku, potřebovat ke spuštění obchodní logiky při ObjectDataSource
čtení nebo aktualizaci dat. Když například aktualizujete oddělení, budete muset ověřit, že žádné jiné oddělení nemají stejného správce, protože jedna osoba nemůže být správcem více než jednoho oddělení.
V některých ObjectDataSource
dokumentech, jako je například ObjectDataSource – přehled třídy, volá ovládací prvek třídu označovanou jako obchodní objekt , který zahrnuje obchodní logiku i logiku přístupu k datům. V tomto kurzu vytvoříte samostatné třídy pro obchodní logiku a logiku přístupu k datům. Třída, která zapouzdřuje logiku přístupu k datům, se nazývá úložiště. Třída obchodní logiky zahrnuje metody obchodní logiky i metody přístupu k datům, ale metody přístupu k datům volají úložiště, aby prováděly úlohy přístupu k datům.
Vytvoříte také abstraktní vrstvu mezi BLL a DAL, která usnadňuje automatizované testování jednotek BLL. Tato vrstva abstrakce se implementuje vytvořením rozhraní a použitím rozhraní při vytváření instance úložiště ve třídě obchodní logiky. To vám umožní poskytnout třídu obchodní logiky s odkazem na jakýkoli objekt, který implementuje rozhraní úložiště. Pro normální provoz zadáte objekt úložiště, který funguje s rozhraním Entity Framework. Pro účely testování poskytnete objekt úložiště, který pracuje s daty uloženými způsobem, se kterým můžete snadno manipulovat, například s proměnnými tříd definovanými jako kolekce.
Následující obrázek znázorňuje rozdíl mezi třídou obchodní logiky, která zahrnuje logiku přístupu k datům bez úložiště, a třídou, která používá úložiště.
Začnete vytvořením webových stránek, na kterých ObjectDataSource
je ovládací prvek vázán přímo na úložiště, protože provádí pouze základní úlohy přístupu k datům. V dalším kurzu vytvoříte třídu obchodní logiky s logikou ověřování a svážete ObjectDataSource
ovládací prvek s danou třídou místo s třídou úložiště. Vytvoříte také testy jednotek pro logiku ověřování. Ve třetím kurzu v této sérii přidáte do aplikace funkci řazení a filtrování.
Stránky, které vytvoříte v tomto kurzu, pracují se Departments
sadou entit datového modelu, který jste vytvořili v sérii kurzů Začínáme.
Aktualizace databáze a datového modelu
Tento kurz zahájíte provedením dvou změn v databázi, které vyžadují odpovídající změny datového modelu, který jste vytvořili v Začínáme s Entity Framework a Web Forms kurzy. V jednom z těchto kurzů jste provedli změny v návrháři ručně, abyste po změně databáze synchronizovali datový model s databází. V tomto kurzu použijete nástroj Aktualizovat model z databáze od návrháře k automatické aktualizaci datového modelu.
Přidání relace do databáze
V sadě Visual Studio otevřete webovou aplikaci Contoso University, kterou jste vytvořili v Začínáme s řadou kurzů Entity Framework a Web Forms, a pak otevřete SchoolDiagram
diagram databáze.
Když se podíváte na Department
tabulku v diagramu databáze, uvidíte, že obsahuje Administrator
sloupec. Tento sloupec je cizím klíčem tabulky Person
, ale v databázi není definován žádný vztah cizího klíče. Musíte vytvořit relaci a aktualizovat datový model tak, aby Entity Framework mohl tuto relaci automaticky zpracovat.
V diagramu databáze klikněte pravým tlačítkem na Department
tabulku a vyberte Relace.
V poli Relace cizího klíče klikněte na Přidat a potom klikněte na tři tečky pro Tabulky a sloupce Specifikace.
V dialogovém okně Tabulky a sloupce nastavte tabulku a pole primárního klíče na Person
a PersonID
a nastavte tabulku a pole cizího klíče na Department
a Administrator
. (Když to uděláte, název relace se změní z FK_Department_Department
na FK_Department_Person
.)
Klikněte na OK v poli Tabulky a sloupce, v poli Relace cizího klíče klikněte na Zavřít a uložte změny. Pokud se zobrazí dotaz, jestli chcete tabulky a Department
uložitPerson
, klikněte na Ano.
Poznámka
Pokud jste odstranili Person
řádky, které odpovídají datům, která už jsou ve sloupci Administrator
, nebudete moct tuto změnu uložit. V takovém případě použijte editor tabulek v Průzkumníku serveru a ujistěte se, že Administrator
hodnota v každém Department
řádku obsahuje ID záznamu Person
, který v tabulce skutečně existuje.
Po uložení změny nebudete moct odstranit řádek z Person
tabulky, pokud je tato osoba správcem oddělení. V produkční aplikaci byste zadali konkrétní chybovou zprávu, když omezení databáze brání odstranění, nebo byste zadali kaskádové odstranění. Příklad určení kaskádového odstranění najdete v tématu Entity Framework a ASP.NET – Začínáme část 2.
Přidání zobrazení do databáze
Na nové stránce Departments.aspx , kterou budete vytvářet, chcete zadat rozevírací seznam instruktorů se jmény ve formátu "příjmení, první", aby uživatelé mohli vybrat správce oddělení. Abyste to usnadnili, vytvoříte v databázi zobrazení. Zobrazení se bude skládat jenom z dat potřebných v rozevíracím seznamu: celého jména (správně naformátovaného) a klíče záznamu.
V Průzkumníku serveru rozbalte School.mdf, klikněte pravým tlačítkem na složku Zobrazení a vyberte Přidat nové zobrazení.
Po zobrazení dialogového okna Přidat tabulku klikněte na Zavřít a vložte do podokna SQL následující příkaz SQL:
SELECT LastName + ',' + FirstName AS FullName, PersonID
FROM dbo.Person
WHERE (HireDate IS NOT NULL)
Uložte zobrazení jako vInstructorName
.
Aktualizace datového modelu
Ve složce DAL otevřete soubor SchoolModel.edmx , klikněte pravým tlačítkem na návrhovou plochu a vyberte Aktualizovat model z databáze.
V dialogovém okně Zvolte databázové objekty vyberte kartu Přidat a vyberte zobrazení, které jste právě vytvořili.
Klikněte na Finish (Dokončit).
V návrháři vidíte, že nástroj vytvořil entitu vInstructorName
a nové přidružení mezi Department
entitami a Person
.
Poznámka
V oknech Výstup a Seznam chyb se může zobrazit zpráva s upozorněním, že nástroj automaticky vytvořil primární klíč pro nové vInstructorName
zobrazení. Toto chování je očekávané.
Když odkazujete na novou vInstructorName
entitu v kódu, nechcete používat konvenci databáze, která předponuje malé písmeno "v". Proto entitu a sadu entit v modelu přejmenujete.
Otevřete Prohlížeč modelů. Zobrazí se vInstructorName
jako typ entity a zobrazení.
V části SchoolModel (ne SchoolModel.Store) klikněte pravým tlačítkem na vInstructorName a vyberte Vlastnosti. V okně Vlastnosti změňte vlastnost Name na InstructorName a změňte vlastnost Název sady entit na InstructorNames.
Uložte a zavřete datový model a pak projekt znovu sestavte.
Použití třídy úložiště a ovládacího prvku ObjectDataSource
Ve složce DAL vytvořte nový soubor třídy, pojmenujte ho SchoolRepository.cs a nahraďte stávající kód následujícím kódem:
using System;
using System.Collections.Generic;
using System.Linq;
using ContosoUniversity.DAL;
namespace ContosoUniversity.DAL
{
public class SchoolRepository : IDisposable
{
private SchoolEntities context = new SchoolEntities();
public IEnumerable<Department> GetDepartments()
{
return context.Departments.Include("Person").ToList();
}
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
context.Dispose();
}
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
Tento kód poskytuje jednu GetDepartments
metodu, která vrací všechny entity v Departments
sadě entit. Protože víte, že budete přistupovat k Person
navigační vlastnosti pro každý vrácený řádek, určíte dychtivé načítání pro tuto vlastnost pomocí Include
metody . Třída také implementuje IDisposable
rozhraní, aby se zajistilo, že připojení k databázi je uvolněno při odstranění objektu.
Poznámka
Běžným postupem je vytvořit třídu úložiště pro každý typ entity. V tomto kurzu se používá jedna třída úložiště pro více typů entit. Další informace o vzoru úložiště najdete v příspěvcích na blogu týmu Entity Framework a v blogu Julie Lermanové.
Metoda GetDepartments
vrací IEnumerable
objekt místo objektu IQueryable
, aby se zajistilo, že vrácená kolekce je použitelná i po odstranění samotného objektu úložiště. Objekt IQueryable
může způsobit přístup k databázi při každém přístupu, ale objekt úložiště může být odstraněn v době, kdy se ovládací prvek příchozích dat pokusí data vykreslit. Můžete vrátit jiný typ kolekce, například IList
objekt místo objektu IEnumerable
. Vrácení objektu IEnumerable
však zajistí, že můžete provádět typické úlohy zpracování seznamu jen pro čtení, jako foreach
jsou smyčky a dotazy LINQ, ale nemůžete přidávat nebo odebírat položky v kolekci, což může znamenat, že takové změny budou zachovány v databázi.
Vytvořte stránku Departments.aspx, která používá stránku site.master, a přidejte do ovládacího prvku s názvem Content2
následující kód Content
:
<h2>Departments</h2>
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments" >
</asp:ObjectDataSource>
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" >
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="True"
ItemStyle-VerticalAlign="Top">
</asp:CommandField>
<asp:DynamicField DataField="Name" HeaderText="Name" SortExpression="Name" ItemStyle-VerticalAlign="Top" />
<asp:DynamicField DataField="Budget" HeaderText="Budget" SortExpression="Budget" ItemStyle-VerticalAlign="Top" />
<asp:DynamicField DataField="StartDate" HeaderText="Start Date" ItemStyle-VerticalAlign="Top" />
<asp:TemplateField HeaderText="Administrator" SortExpression="Person.LastName" ItemStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label ID="AdministratorLastNameLabel" runat="server" Text='<%# Eval("Person.LastName") %>'></asp:Label>,
<asp:Label ID="AdministratorFirstNameLabel" runat="server" Text='<%# Eval("Person.FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Tento kód vytvoří ovládací prvek ObjectDataSource
, který používá třídu úložiště, kterou jste právě vytvořili, a GridView
ovládací prvek k zobrazení dat. Ovládací GridView
prvek určuje příkazy Upravit a Odstranit , ale ještě jste nepřidali kód pro jejich podporu.
Několik sloupců používá DynamicField
ovládací prvky, abyste mohli využít výhod automatického formátování a funkce ověřování dat. Aby tyto funkce fungovaly, budete muset volat metodu EnableDynamicData
v obslužné rutině Page_Init
události. (DynamicControl
Ovládací prvky se v Administrator
poli nepoužívají, protože nefungují s navigačními vlastnostmi.)
Atributy Vertical-Align="Top"
se stanou důležitými později, když do mřížky přidáte sloupec s vnořeným GridView
ovládacím prvkem.
Otevřete soubor Departments.aspx.cs a přidejte následující using
příkaz:
using ContosoUniversity.DAL;
Pak přidejte následující obslužnou rutinu pro událost stránky Init
:
protected void Page_Init(object sender, EventArgs e)
{
DepartmentsGridView.EnableDynamicData(typeof(Department));
}
Ve složce DAL vytvořte nový soubor třídy s názvem Department.cs a nahraďte stávající kód následujícím kódem:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.DAL
{
[MetadataType(typeof(DepartmentMetaData))]
public partial class Department
{
}
public class DepartmentMetaData
{
[DataType(DataType.Currency)]
[Range(0, 1000000, ErrorMessage = "Budget must be less than $1,000,000.00")]
public Decimal Budget { get; set; }
[DisplayFormat(DataFormatString="{0:d}",ApplyFormatInEditMode=true)]
public DateTime StartDate { get; set; }
}
}
Tento kód přidá metadata do datového modelu. Určuje, že Budget
vlastnost Department
entity ve skutečnosti představuje měnu, i když její datový typ je Decimal
, a určuje, že hodnota musí být mezi 0 a 1 000 000,00 USD. Určuje také, že StartDate
vlastnost by měla být formátována jako datum ve formátu mm/dd/rrrr.
Spusťte stránku Departments.aspx .
Všimněte si, že i když jste v kódu stránky Departments.aspx pro sloupce Rozpočet nebo Počáteční datum nezadali formátovací řetězec, ovládací prvky na ně DynamicField
použily výchozí formátování měny a data pomocí metadat, která jste zadali v souboru Department.cs .
Přidání funkcí vložení a odstranění
Otevřete SchoolRepository.cs a přidejte následující kód, abyste vytvořili metodu Insert
a metodu Delete
. Kód také obsahuje metodu s názvem GenerateDepartmentID
, která vypočítá další dostupnou hodnotu klíče záznamu pro použití metodou Insert
. To je povinné, protože databáze není nakonfigurovaná tak, aby tuto hodnotu automaticky vypočítala Department
pro tabulku.
public void InsertDepartment(Department department)
{
try
{
department.DepartmentID = GenerateDepartmentID();
context.Departments.AddObject(department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
public void DeleteDepartment(Department department)
{
try
{
context.Departments.Attach(department);
context.Departments.DeleteObject(department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
private Int32 GenerateDepartmentID()
{
Int32 maxDepartmentID = 0;
var department = (from d in GetDepartments()
orderby d.DepartmentID descending
select d).FirstOrDefault();
if (department != null)
{
maxDepartmentID = department.DepartmentID + 1;
}
return maxDepartmentID;
}
Metoda Attach
Metoda DeleteDepartment
volá metodu Attach
za účelem opětovného vytvoření propojení, které je udržováno ve správci stavu objektu kontextu objektu mezi entitou v paměti a databázovým řádkem, který představuje. K tomu musí dojít dříve, než metoda zavolá metodu SaveChanges
.
Termín kontext objektu odkazuje na třídu Entity Framework, která je odvozena od ObjectContext
třídy, kterou používáte pro přístup k vašim sadám entit a entitám. V kódu pro tento projekt má třída název SchoolEntities
a instance je vždy pojmenována context
. Správce stavu objektu kontextu objektu je třída, která je odvozena od ObjectStateManager
třídy. Kontakt objektu používá správce stavu objektu k ukládání objektů entit a ke sledování toho, jestli je každý z nich synchronizovaný s odpovídajícím řádkem tabulky nebo řádky v databázi.
Když čtetete entitu, kontext objektu ji uloží do správce stavu objektu a sleduje, jestli je tato reprezentace objektu synchronizovaná s databází. Pokud například změníte hodnotu vlastnosti, nastaví se příznak, který označuje, že vlastnost, kterou jste změnili, už není synchronizovaná s databází. Když pak zavoláte metodu SaveChanges
, kontext objektu ví, co dělat v databázi, protože správce stavu objektu přesně ví, co se liší mezi aktuálním stavem entity a stavem databáze.
Tento proces však obvykle nefunguje ve webové aplikaci, protože instance kontextu objektu, která čte entitu, spolu se vším v jejím správci stavu objektu, je odstraněna po vykreslení stránky. Instance kontextu objektu, která musí použít změny, je nová instance, která je vytvořena pro následné zpracování. V případě DeleteDepartment
metody ObjectDataSource
ovládací prvek znovu vytvoří původní verzi entity z hodnot ve stavu zobrazení, ale tato znovu vytvořená Department
entita neexistuje ve správci stavu objektů. Pokud jste volali metodu DeleteObject
pro tuto znovu vytvořenou entitu, volání by selhalo, protože kontext objektu neví, jestli je entita synchronizovaná s databází. Volání Attach
metody však znovu vytvoří stejné sledování mezi znovu vytvořenou entitou a hodnotami v databázi, které bylo původně provedeno automaticky při čtení entity v dřívější instanci kontextu objektu.
Existují chvíle, kdy nechcete, aby kontext objektu sledoval entity ve správci stavu objektů, a můžete nastavit příznaky, které mu v tom zabrání. Příklady jsou uvedeny v dalších kurzech v této sérii.
The SaveChanges – metoda
Tato jednoduchá třída úložiště znázorňuje základní principy provádění operací CRUD. V tomto příkladu SaveChanges
je metoda volána ihned po každé aktualizaci. V produkční aplikaci můžete chtít volat metodu SaveChanges
ze samostatné metody, abyste měli větší kontrolu nad tím, kdy se databáze aktualizuje. (Na konci dalšího kurzu najdete odkaz na dokument white paper, který popisuje vzor jednotek práce, což je jeden z přístupů ke koordinaci souvisejících aktualizací.) Všimněte si také, že v příkladu DeleteDepartment
metoda neobsahuje kód pro zpracování konfliktů souběžnosti; kód, který bude přidán v pozdějším kurzu v této sérii.
Načítání jmen instruktorů, které se mají vybrat při vkládání
Uživatelé musí mít možnost vybrat správce ze seznamu instruktorů v rozevíracím seznamu při vytváření nových oddělení. Proto do souboru SchoolRepository.cs přidejte následující kód, který vytvoří metodu pro načtení seznamu instruktorů pomocí zobrazení, které jste vytvořili dříve:
public IEnumerable<InstructorName> GetInstructorNames()
{
return context.InstructorNames.OrderBy("it.FullName").ToList();
}
Vytvoření stránky pro vkládání oddělení
Vytvořte stránku DepartmentsAdd.aspx , která používá stránku Site.Master , a přidejte následující kód do Content
ovládacího prvku s názvem Content2
:
<h2>Departments</h2>
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository" DataObjectTypeName="ContosoUniversity.DAL.Department"
InsertMethod="InsertDepartment" >
</asp:ObjectDataSource>
<asp:DetailsView ID="DepartmentsDetailsView" runat="server"
DataSourceID="DepartmentsObjectDataSource" AutoGenerateRows="False"
DefaultMode="Insert" OnItemInserting="DepartmentsDetailsView_ItemInserting">
<Fields>
<asp:DynamicField DataField="Name" HeaderText="Name" />
<asp:DynamicField DataField="Budget" HeaderText="Budget" />
<asp:DynamicField DataField="StartDate" HeaderText="Start Date" />
<asp:TemplateField HeaderText="Administrator">
<InsertItemTemplate>
<asp:ObjectDataSource ID="InstructorsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.InstructorName"
SelectMethod="GetInstructorNames" >
</asp:ObjectDataSource>
<asp:DropDownList ID="InstructorsDropDownList" runat="server"
DataSourceID="InstructorsObjectDataSource"
DataTextField="FullName" DataValueField="PersonID" OnInit="DepartmentsDropDownList_Init">
</asp:DropDownList>
</InsertItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
<asp:ValidationSummary ID="DepartmentsValidationSummary" runat="server"
ShowSummary="true" DisplayMode="BulletList" />
Tento kód vytvoří dva ObjectDataSource
ovládací prvky, jeden pro vkládání nových Department
entit a druhý pro načtení názvů instruktorů pro DropDownList
ovládací prvek, který se používá pro výběr správců oddělení. Kód vytvoří DetailsView
ovládací prvek pro zadávání nových oddělení a určuje obslužnou rutinu pro událost ovládacího prvku ItemInserting
, abyste mohli nastavit hodnotu cizího Administrator
klíče. Na konci je ovládací prvek ValidationSummary
pro zobrazení chybových zpráv.
Otevřete DepartmentsAdd.aspx.cs a přidejte následující using
příkaz:
using ContosoUniversity.DAL;
Přidejte následující proměnnou třídy a metody:
private DropDownList administratorsDropDownList;
protected void Page_Init(object sender, EventArgs e)
{
DepartmentsDetailsView.EnableDynamicData(typeof(Department));
}
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
administratorsDropDownList = sender as DropDownList;
}
protected void DepartmentsDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
e.Values["Administrator"] = administratorsDropDownList.SelectedValue;
}
Metoda Page_Init
umožňuje funkci dynamických dat. Obslužná rutina události DropDownList
ovládacího prvku Init
uloží odkaz na ovládací prvek a obslužná rutina Inserting
události DetailsView
ovládacího prvku použije tento odkaz k získání PersonID
hodnoty vybraného instruktora a aktualizaci Administrator
vlastnosti cizího Department
klíče entity.
Spusťte stránku, přidejte informace pro nové oddělení a klikněte na odkaz Vložit .
Zadejte hodnoty pro jiné nové oddělení. Do pole Rozpočet zadejte číslo větší než 1 000 000,00 a tabulátorem přejděte na další pole. V poli se zobrazí hvězdička, a pokud na ni podržíte ukazatel myši, zobrazí se chybová zpráva, kterou jste zadali v metadatech pro toto pole.
Klikněte na Vložit a zobrazí se chybová zpráva zobrazená ovládacím ValidationSummary
prvku v dolní části stránky.
Pak zavřete prohlížeč a otevřete stránku Departments.aspx . Přidejte možnost odstranění na stránku Departments.aspx přidáním atributu DeleteMethod
ObjectDataSource
do ovládacího prvku a DataKeyNames
atributu GridView
do ovládacího prvku. Počáteční značky pro tyto ovládací prvky se teď budou podobat následujícímu příkladu:
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments"
DeleteMethod="DeleteDepartment" >
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" >
Spusťte stránku.
Odstraňte oddělení, které jste přidali při spuštění stránky DepartmentsAdd.aspx .
Přidání funkce aktualizace
Otevřete Soubor SchoolRepository.cs a přidejte následující Update
metodu:
public void UpdateDepartment(Department department, Department origDepartment)
{
try
{
context.Departments.Attach(origDepartment);
context.ApplyCurrentValues("Departments", department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
Když kliknete na Aktualizovat na stránce Departments.aspx , ObjectDataSource
ovládací prvek vytvoří dvě Department
entity, které se předávají UpdateDepartment
metodě. Jedna obsahuje původní hodnoty, které byly uloženy ve stavu zobrazení, a druhá obsahuje nové hodnoty, které byly zadány v ovládacím GridView
prvku. Kód v UpdateDepartment
metodě předá entitu Department
, která má původní hodnoty, metodě Attach
, aby bylo možné vytvořit sledování mezi entitou a tím, co je v databázi. Pak kód předá entitu Department
, která má nové hodnoty, metodě ApplyCurrentValues
. Kontext objektu porovnává staré a nové hodnoty. Pokud se nová hodnota liší od staré hodnoty, kontext objektu změní hodnotu vlastnosti. Metoda SaveChanges
pak aktualizuje pouze změněné sloupce v databázi. (Pokud by však funkce aktualizace pro tuto entitu byla namapována na uloženou proceduru, celý řádek by se aktualizoval bez ohledu na to, které sloupce byly změněny.)
Otevřete soubor Departments.aspx a přidejte do DepartmentsObjectDataSource
ovládacího prvku následující atributy:
UpdateMethod="UpdateDepartment"
ConflictDetection="CompareAllValues"
To způsobí, že staré hodnoty budou uloženy ve stavu zobrazení, aby je bylo možné porovnat s novými hodnotami vUpdate
metodě.OldValuesParameterFormatString="orig{0}"
To informuje ovládací prvek, že název původního parametru hodnot jeorigDepartment
.
Kód pro počáteční značku ovládacího prvku ObjectDataSource
se teď podobá následujícímu příkladu:
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments" DeleteMethod="DeleteDepartment"
UpdateMethod="UpdateDepartment"
ConflictDetection="CompareAllValues"
OldValuesParameterFormatString="orig{0}" >
OnRowUpdating="DepartmentsGridView_RowUpdating"
Přidejte do GridView
ovládacího prvku atribut. Použijete ji k nastavení Administrator
hodnoty vlastnosti na základě řádku, který uživatel vybere v rozevíracím seznamu. Počáteční GridView
značka se teď podobá následujícímu příkladu:
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating">
Přidejte ovládací prvek EditItemTemplate
pro sloupec do GridView
ovládacího prvku hned za ItemTemplate
ovládací prvek Administrator
pro daný sloupec:
<EditItemTemplate>
<asp:ObjectDataSource ID="InstructorsObjectDataSource" runat="server" DataObjectTypeName="ContosoUniversity.DAL.InstructorName"
SelectMethod="GetInstructorNames" TypeName="ContosoUniversity.DAL.SchoolRepository">
</asp:ObjectDataSource>
<asp:DropDownList ID="InstructorsDropDownList" runat="server" DataSourceID="InstructorsObjectDataSource"
SelectedValue='<%# Eval("Administrator") %>'
DataTextField="FullName" DataValueField="PersonID" OnInit="DepartmentsDropDownList_Init" >
</asp:DropDownList>
</EditItemTemplate>
Tento EditItemTemplate
ovládací prvek je podobný ovládacímu InsertItemTemplate
prvku na stránce DepartmentsAdd.aspx . Rozdíl je v tom, že počáteční hodnota ovládacího prvku je nastavena pomocí atributu SelectedValue
.
Před ovládací prvek GridView
přidejte ValidationSummary
ovládací prvek, jak jste to udělali na stránce DepartmentsAdd.aspx .
<asp:ValidationSummary ID="DepartmentsValidationSummary" runat="server"
ShowSummary="true" DisplayMode="BulletList" />
Otevřete Departments.aspx.cs a ihned po deklaraci částečné třídy přidejte následující kód pro vytvoření privátního pole odkazovaného na DropDownList
ovládací prvek:
private DropDownList administratorsDropDownList;
Pak přidejte obslužné rutiny pro DropDownList
událost ovládacího prvku Init
a GridView
událost ovládacího prvku RowUpdating
:
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
administratorsDropDownList = sender as DropDownList;
}
protected void DepartmentsGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
e.NewValues["Administrator"] = administratorsDropDownList.SelectedValue;
}
Obslužná rutina události Init
uloží odkaz na DropDownList
ovládací prvek v poli třídy. Obslužná rutina události RowUpdating
používá odkaz k získání hodnoty, kterou uživatel zadal, a použije ji pro Administrator
vlastnost Department
entity.
Pomocí stránky DepartmentsAdd.aspx přidejte nové oddělení, spusťte stránku Departments.aspx a klikněte na upravit na řádku, který jste přidali.
Poznámka
Nebudete moci upravit řádky, které jste nepřidali (to znamená, že již byly v databázi), z důvodu neplatných dat v databázi; správci řádků vytvořených s databází jsou studenti. Pokud se pokusíte některý z nich upravit, zobrazí se chybová stránka, která hlásí chybu, například 'InstructorsDropDownList' has a SelectedValue which is invalid because it does not exist in the list of items.
Pokud zadáte neplatnou částku rozpočtu a potom kliknete na Aktualizovat, zobrazí se stejná hvězdička a chybová zpráva, jakou jste viděli na stránce Departments.aspx .
Změňte hodnotu pole nebo vyberte jiného správce a klikněte na Aktualizovat. Zobrazí se změna.
Tím se dokončí úvod k používání ObjectDataSource
ovládacího prvku pro základní operace CRUD (vytvoření, čtení, aktualizace, odstranění) s rozhraním Entity Framework. Vytvořili jste jednoduchou n-vrstvou aplikaci, ale vrstva obchodní logiky je stále úzce spojená s vrstvou přístupu k datům, což komplikuje automatizované testování částí. V následujícím kurzu se dozvíte, jak implementovat vzor úložiště pro usnadnění testování částí.