Entity Framework 4.0 Database First と ASP.NET 4 Web Forms を使用したはじめに - パート 5
Contoso University サンプル Web アプリケーションは、Entity Framework 4.0 と Visual Studio 2010 を使用して ASP.NET Web Forms アプリケーションを作成する方法を示しています。 チュートリアル シリーズの詳細については、シリーズの最初のチュートリアルを参照してください
関連データの操作、続き
前のチュートリアルでは、 コントロールを使用 EntityDataSource
して関連データを操作し始めました。 複数レベルの階層と編集されたデータをナビゲーション プロパティに表示しました。 このチュートリアルでは、リレーションシップを追加および削除し、既存のエンティティにリレーションシップを持つ新しいエンティティを追加することで、関連データを引き続き操作します。
部署に割り当てられているコースを追加するページを作成します。 部門は既に存在し、新しいコースを作成すると同時に、その部門と既存の部門の間に関係が確立されます。
また、コースに講師を割り当てる (選択した 2 つのエンティティ間のリレーションシップを追加する) か、コースから講師を削除する (選択した 2 つのエンティティ間のリレーションシップを削除する) ことも、多対多リレーションシップで動作するページを作成します。 データベースで、インストラクターとコースの間にリレーションシップを追加すると、関連付けテーブルに CourseInstructor
新しい行が追加されます。リレーションシップを削除するには、関連付けテーブルから行を削除する CourseInstructor
必要があります。 ただし、エンティティ フレームワークでは、テーブルを明示的に参照せずにナビゲーション プロパティを CourseInstructor
設定することでこれを行います。
リレーションシップを持つエンティティを既存のエンティティに追加する
Site.Master マスター ページを使用する CoursesAdd.aspx という名前の新しい Web ページを作成し、 という名前Content2
のコントロールに次のマークアップをContent
追加します。
<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>
このマークアップは、コースを EntityDataSource
選択し、挿入を有効にし、イベントのハンドラーを指定するコントロールを Inserting
作成します。 ハンドラーを使用して、新しいCourse
エンティティの作成時にDepartment
ナビゲーション プロパティを更新します。
マークアップでは、新しいCourse
エンティティのDetailsView
追加に使用するコントロールも作成されます。 マークアップでは、エンティティ プロパティにバインドされたフィールドが Course
使用されます。 この値はシステムによって生成される ID フィールドではないので、値を入力 CourseID
する必要があります。 代わりに、コースの作成時に手動で指定する必要があるコース番号です。
ナビゲーション プロパティはコントロールで使用できないため、 Department
ナビゲーション プロパティにはテンプレート フィールドを BoundField
使用します。 テンプレート フィールドには、部門を選択するためのドロップダウン リストが表示されます。 ドロップダウン リストは、 ではなく Bind
をDepartments
使用Eval
してエンティティ セットにバインドされます。これは、ナビゲーション プロパティを更新するために直接バインドできないためです。 外部キーを更新する DropDownList
コードで使用するコントロール Init
への参照を格納できるように、コントロールのイベントのハンドラーを DepartmentID
指定します。
部分クラス宣言の直後の CoursesAdd.aspx.cs で、コントロールへの参照を保持するクラス フィールドを DepartmentsDropDownList
追加します。
private DropDownList departmentDropDownList;
コントロールへの参照を DepartmentsDropDownList
格納できるように、コントロールのイベントの Init
ハンドラーを追加します。 これにより、ユーザーが入力した値を取得し、それを使用してエンティティの値をDepartmentID
Course
更新できます。
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
departmentDropDownList = sender as DropDownList;
}
コントロールInserting
のイベントのハンドラーをDetailsView
追加します。
protected void CoursesDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
var departmentID = Convert.ToInt32(departmentDropDownList.SelectedValue);
e.Values["DepartmentID"] = departmentID;
}
ユーザーが をクリック Insert
すると、 Inserting
新しいレコードが挿入される前にイベントが発生します。 ハンドラーのコードは、コントロールから をDepartmentID
DropDownList
取得し、それを使用してエンティティの プロパティに使用DepartmentID
される値をCourse
設定します。
Entity Framework は、関連付けられたDepartment
エンティティのナビゲーション プロパティにCourses
このコースを追加します。 また、エンティティのナビゲーション プロパティに Department
部署を Course
追加します。
ページを実行します。
ID、タイトル、クレジットの数を入力し、部署を選択して、[ 挿入] をクリックします。
Courses.aspx ページを実行し、同じ部署を選択して新しいコースを表示します。
多対多リレーションシップの操作
エンティティ セットとエンティティ セットの Courses
間の People
リレーションシップは、多対多リレーションシップです。 Course
エンティティには、 という名前People
のナビゲーション プロパティがあり、0 個、1 つ以上の関連Person
エンティティ (そのコースを教えるために割り当てられた講師を表します) を含めることができます。 また、 Person
エンティティには という名前 Courses
のナビゲーション プロパティがあり、0 個、1 つ以上の関連 Course
エンティティ (講師が教えるために割り当てられているコースを表します) を含めることができます。 1 人の講師が複数のコースを教え、1 つのコースが複数の講師によって教えられる場合があります。 チュートリアルのこのセクションでは、関連エンティティのナビゲーション プロパティを更新して、 と Course
エンティティの間Person
のリレーションシップを追加および削除します。
Site.Master マスター ページを使用する InstructorsCourses.aspx という名前の新しい Web ページを作成し、 という名前Content2
のコントロールに次のマークアップをContent
追加します。
<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>
このマークアップは、講師のEntityDataSource
エンティティのPerson
名前とPersonID
エンティティを取得するコントロールを作成します。 DropDrownList
コントロールはコントロールにEntityDataSource
バインドされます。 コントロールは DropDownList
、イベントのハンドラーを DataBound
指定します。 このハンドラーを使用して、コースを表示する 2 つのドロップダウン リストをデータバインドします。
マークアップでは、選択した講師にコースを割り当てるために使用する次のコントロールのグループも作成されます。
DropDownList
割り当てるコースを選択するためのコントロール。 このコントロールには、選択した講師に現在割り当てられないコースが設定されます。Button
割り当てを開始するコントロール。Label
割り当てが失敗した場合にエラー メッセージを表示するコントロール。
最後に、マークアップでは、選択したインストラクターからコースを削除するために使用するコントロールのグループも作成されます。
InstructorsCourses.aspx.cs で、using ステートメントを追加します。
using ContosoUniversity.DAL;
コースを表示する 2 つのドロップダウン リストを設定するためのメソッドを追加します。
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;
}
}
このコードは、エンティティ セットからすべてのコースを Courses
取得し、選択したインストラクターの Courses
エンティティの Person
ナビゲーション プロパティからコースを取得します。 次に、その講師に割り当てられているコースを決定し、それに応じてドロップダウン リストを設定します。
ボタンClick
のイベントのハンドラーをAssign
追加します。
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;
}
}
このコードは、選択したインストラクターのPerson
エンティティを取得し、選択したコースのエンティティを取得Course
し、選択したコースを講師のPerson
エンティティのナビゲーション プロパティにCourses
追加します。 その後、データベースへの変更を保存し、ドロップダウン リストを再入力して、結果をすぐに確認できるようにします。
ボタンClick
のイベントのハンドラーをRemove
追加します。
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;
}
}
このコードは、選択したインストラクターの Person
エンティティを取得し、選択したコースのエンティティを取得 Course
し、選択したコースを Person
エンティティの Courses
ナビゲーション プロパティから削除します。 その後、データベースへの変更を保存し、ドロップダウン リストを再入力して、結果をすぐに確認できるようにします。
報告するPage_Load
エラーがないときにエラー メッセージが表示されないようにするコードを メソッドに追加し、講師の ドロップダウン リストの イベントと SelectedIndexChanged
イベントのハンドラーDataBound
を追加して、コースのドロップダウン リストを設定します。
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();
}
ページを実行します。
講師を選択します。 [ コースの割り当て ] ドロップダウン リストには、講師が教えていないコースが表示され、[コースの 削除 ] ドロップダウン リストには、講師が既に割り当てられているコースが表示されます。 [ コースの割り当て ] セクションで、コースを選択し、[ 割り当て] をクリックします。 コースが [コースの 削除 ] ドロップダウン リストに移動します。 [コースの削除] セクションでコースを選択し、[削除] をクリックします。コースが [コースの割り当て] ドロップダウン リストに移動します。
これで、関連データを操作するいくつかの方法が見られました。 次のチュートリアルでは、データ モデルで継承を使用して、アプリケーションの保守性を向上させる方法について説明します。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示