チュートリアル: 外部キー プロパティを使用したエンティティの追加 (Entity Framework)

このトピックでは、エンティティ プロパティとして公開された外部キーにより概念モデルを生成する方法について説明し、エンティティおよびリレーションシップを作成するためにコードを記述する方法について説明します。

Visual Studio 2010 以降では、既存のデータベースからモデルを生成する場合、ADO.NET Entity Data Model デザイナー (エンティティ デザイナー) は、データベースの外部キー列に対応するエンティティ型のスカラー プロパティを作成します。 外部キー プロパティを使用し、エンティティ型の間のリレーションシップの作成および変更を実行できます。 既定では、エンティティ デザイナーは、リレーションシップの作成および変更に使用できる、エンティティ型のナビゲーション プロパティも生成します。 このチュートリアルでは、外部キー プロパティおよびナビゲーション プロパティを使用し、リレーションシップを作成する方法について説明します。 外部キー プロパティを使用してリレーションシップの作成および管理を実行すると、一般的なシナリオの多くが簡素化されます。 たとえば、外部キー プロパティを使用してリレーションシップの作成および管理を行うと、データ バインド、同時実行制御、および n 層シナリオを簡素化できます。 詳細については、「Defining and Managing Relationships」を参照してください。

前提条件

このチュートリアルを完了するには、Visual Studio 2010 以降をコンピューターにインストール済みであること、および School サンプル データベースを含む SQL Server インスタンスへのアクセスが必要です。 詳細については、「Creating the School Sample Database」を参照してください。

このチュートリアルでは、Visual Studio、.NET Framework、および Visual C# または Visual Basic のプログラミングの基本的なスキルがある読者を想定しています。

.edmx ファイルの生成

この手順を完了するには、Visual Studio で新しい WPF アプリケーション プロジェクトを開いておく必要があります。 この手順では、School サンプル データベースの 2 つのテーブルに基づき、.edmx ファイルを生成します。 .edmx ファイルには、概念モデル、ストレージ モデル、およびこれらの間のマッピングが含まれています。 詳細については、「.edmx ファイルの概要 (Entity Framework)」を参照してください。 生成された概念モデルのエンティティ型には、データベースの外部キー列に対応するスカラー プロパティがあります。

.edmx ファイルを生成するには

  1. ソリューション エクスプローラーで、プロジェクト名を右クリックして [追加] をポイントし、[新しい項目] を選択します。

    [新しい項目の追加] ダイアログ ボックスが表示されます。

  2. [ADO.NET Entity Data Model] を選択し、[追加] をクリックします (表示するテンプレートの数を少なくする場合は、[インストールされているテンプレート] の下の**[データ]** を選択します)。

  3. Entity Data Model ウィザード で、[データベースから生成] を選択し、[次へ] をクリックします。

  4. [データ接続の選択] ダイアログ ボックスで、School サンプル データベースに接続し、[次へ] をクリックします。

  5. [データベース オブジェクトの選択] ダイアログ ボックスで、[テーブル] ノードを展開し、Course テーブルおよび Department テーブルを選択します。 既定では、[生成されたオブジェクトの名前を複数化または単数化する] チェック ボックスおよび [モデルに外部キー列を含める] チェック ボックスがオンになっていることに注意してください。 [モデルに外部キー列を含める] チェック ボックスをオンにしたままにすると、データベースの外部キー列にマップされるエンティティ型のスカラー プロパティが作成され、外部キー アソシエーションがエンティティの間に作成されます。 チェック ボックスをオフにすると、エンティティ型の間に独立アソシエーションが作成されます。 詳細については、「Association Element (CSDL)」および「ReferentialConstraint Element (CSDL)」を参照してください。

    [生成されたオブジェクトの名前を複数化または単数化する] チェック ボックスをオンにしたままにすると、エンティティ セット、エンティティ型、およびナビゲーション プロパティの名前に単数形と複数形に関する英語のルールが適用されます。 詳細については、「[データベース オブジェクトの選択] ダイアログ ボックス (Entity Data Model ウィザード)」を参照してください。

    このチュートリアルでは、両方のチェック ボックスをオンにしたままで続行することを前提とします。

  6. [完了] をクリックします。

    .edmx ファイルがプロジェクトに追加され、エンティティ デザイナーに表示されます。 2 つのエンティティ型 (Department および Course) が、それらの間の 1 対多 (1:*) アソシエーションと共に画面に表示されます。 アソシエーションは参照制約を使用して作成され、次の XML エディターで .edmx ファイルを開くと表示できます。

    <Association Name="FK_Course_Department">
      <End Role="Department" Type="SchoolModel.Department" Multiplicity="1" />
      <End Role="Course" Type="SchoolModel.Course" Multiplicity="*" />
      <ReferentialConstraint>
        <Principal Role="Department">
          <PropertyRef Name="DepartmentID" />
        </Principal>
        <Dependent Role="Course">
          <PropertyRef Name="DepartmentID" />
        </Dependent>
      </ReferentialConstraint>
    </Association>
    

    詳細については、「ReferentialConstraint Element (CSDL)」を参照してください。

ユーザー インターフェイスの作成

この手順では、アプリケーションにコントロールを追加して、部門および講座の情報を作成したり更新したりできるようにします。

ユーザー インターフェイスを作成するには

  1. Visual Studio の**[データ]** メニューから [データ ソースの表示] を選択します。

    [データ ソース] ペインが表示されます。

  2. [MainWindow] デザイン画面を表示するには、[MainWindow.xaml] タブをクリックします。

  3. [データ ソース] ペインで、[Courses] データ ソースをクリックし、ドロップダウン リストから [詳細] を選択します。

  4. [Departments] データ ソースについて手順 2 を繰り返します。

  5. [データ ソース] ペインで [Courses] データ ソースを展開し、[DepartmentID] フィールドをクリックして [なし] を選択します。

  6. [データ ソース] ペインで [Departments] データ ソースを展開し、[Name] フィールドをクリックして [ComboBox] を選択します。

  7. [Courses] データ ソースおよび[Departments] データ ソースを [MainWindow] デザイン画面にドラッグします。

    [Courses] データ ソースおよび[Departments] データ ソースの グリッド コントロールが [MainWindow] デザイン画面に作成されます。

  8. [プロパティ] ウィンドウで、[Department ID]、[Budget]、[Start Date]、および [Administrator] の各テキスト ボックスの [IsEnabled] チェック ボックスをオフにします。

  9. [プロパティ] ウィンドウで、[Name] コンボ ボックスの [IsEditable] チェック ボックスをオンにします。

  10. [ツールボックス] から CheckBox コントロールを [MainWindow] デザイン画面にドラッグします。 CheckBox コントロールの名前を newDepartment に変更し、コンテンツ プロパティを New Department に設定します。

  11. [ツールボックス] から Button コントロールを [MainWindow] デザイン画面にドラッグします。 Button コントロールの名前を addWithFKButton に変更し、コンテンツ プロパティを Add (FK) に変更します。

  12. [ツールボックス] から Button コントロールを [MainWindow] デザイン画面にドラッグします。 Button コントロールの名前を addWithNavPropButton に変更し、コンテンツ プロパティを Add (Nav Prop) に変更します。

ユーザー インターフェイスが完成しました。

外部キー プロパティを使用した関連エンティティの追加

この手順では、アプリケーションにコードを追加し、外部キー プロパティを使用して新しい部門および講座を追加できるようにします。

外部キー プロパティを使用して関連エンティティを追加するには

  1. MainWindow.xaml.vb または MainWindow.xaml.cs ファイルを開き、次の Using (C#) ステートメントまたは Imports (Visual Basic) ステートメントを追加します。

    Imports System.Data.Objects
    
    using System.Data.Objects;
    
  2. MainWindow クラスに次のメンバーを追加します。 これは、オブジェクトの追加先となる ObjectContext です。

    Private context As SchoolEntities
    
    private SchoolEntities context;
    
  3. Window_Loaded メソッドのコードを次のコードに置き換えます。このコードは、GridView コントロールに部門を設定します。

    context = New SchoolEntities()
    Dim departmentsViewSource As CollectionViewSource = _
        DirectCast((Me.FindResource("DepartmentsViewSource")),  _
            CollectionViewSource)
    Dim departmentsQuery As ObjectQuery(Of Department) = _
        Me.GetDepartmentsQuery(context)
    departmentsViewSource.Source = _
        departmentsQuery.Execute(MergeOption.AppendOnly)
    
    context = new SchoolEntities();
    CollectionViewSource departmentsViewSource =
        ((CollectionViewSource)(this.FindResource("departmentsViewSource")));
    ObjectQuery<Department> departmentsQuery =
          this.GetDepartmentsQuery(context);
    departmentsViewSource.Source =
        departmentsQuery.Execute(MergeOption.AppendOnly);
    
  4. [MainWindow] デザイン画面で、[New Department] ボタンをダブルクリックします。

    newDepartment_Checked メソッドが分離コード ファイルに追加されます。

  5. newDepartment_Checked メソッドに次のコードを追加します。 これにより、新しい部門を ObjectContext に追加できるようになります。

    Dim departmentsViewSource As CollectionViewSource = _
        DirectCast((FindResource("DepartmentsViewSource")),  _
            CollectionViewSource)
    If newDepartment.IsChecked = True Then
        departmentsViewSource.Source = Nothing
        DepartmentIDTextBox.IsEnabled = True
        BudgetTextBox.IsEnabled = True
        StartDateDatePicker.IsEnabled = True
        AdministratorTextBox.IsEnabled = True
    End If
    
    CollectionViewSource departmentsViewSource =
        (CollectionViewSource)(FindResource("departmentsViewSource"));
    if (newDepartment.IsChecked == true)
    {
        departmentsViewSource.Source = null;
        departmentIDTextBox.IsEnabled = true;
        budgetTextBox.IsEnabled = true;
        startDateDatePicker.IsEnabled = true;
        administratorTextBox.IsEnabled = true;
    }
    
  6. [MainWindow] デザイン画面で、[Add (FK)] ボタンをダブルクリックします。

    addWithFKButton_Click メソッドが分離コード ファイルに追加されます。

  7. addWithFKButton_Click メソッドに次のコードを追加します。 新しい講座の [DepartmentID] プロパティを設定すると、新しい講座が部門に関連付けられます。

    If newDepartment.IsChecked = True Then
        Dim dept As New Department()
        dept.DepartmentID = Convert.ToInt32(DepartmentIDTextBox.Text)
        dept.Name = NameComboBox.Text
        dept.Budget = Convert.ToInt32(BudgetTextBox.Text)
        dept.StartDate = Convert.ToDateTime(StartDateDatePicker.SelectedDate)
        dept.Administrator = Convert.ToInt32(AdministratorTextBox.Text)
        context.Departments.AddObject(dept)
    End If
    
    Dim course As New Course()
    course.CourseID = Convert.ToInt32(CourseIDTextBox.Text)
    course.Title = TitleTextBox.Text
    course.Credits = Convert.ToInt32(CreditsTextBox.Text)
    ' The new course is associated with a department
    ' by setting the DepartmentID property.
    course.DepartmentID = Convert.ToInt32(DepartmentIDTextBox.Text)
    context.Courses.AddObject(course)
    context.SaveChanges()
    
    if (newDepartment.IsChecked == true)
    {
        Department dept = new Department
        {
            DepartmentID = Convert.ToInt32(departmentIDTextBox.Text),
            Name = nameComboBox.Text,
            Budget = Convert.ToInt32(budgetTextBox.Text),
            StartDate = Convert
                      .ToDateTime(startDateDatePicker.SelectedDate),
            Administrator = Convert
                      .ToInt32(administratorTextBox.Text)
        };
        context.Departments.AddObject(dept);
    }
    Course course = new Course
    {
        CourseID = Convert.ToInt32(courseIDTextBox.Text),
        Title = titleTextBox.Text,
        Credits = Convert.ToInt32(creditsTextBox.Text),
        // The new course is associated with a department
        // by setting the DepartmentID property.
        DepartmentID = Convert.ToInt32(departmentIDTextBox.Text)
    };
    context.Courses.AddObject(course);
    context.SaveChanges();
    
Ee828425.note(ja-jp,VS.100).gif注 :
新しい講座および新しい部門を同時に追加する場合、SaveChanges が呼び出されるまで、ナビゲーション プロパティは同期されません。たとえば SaveChanges を呼び出す前に、新しい講座のナビゲーション プロパティにより新しい部門にアクセスしようとする場合、null が返されます。

Crtl+F5 キーを押してプログラムを実行します。 講座情報を編集し、[Add (FK)] をクリックすると、選択した部門に新しい講座を追加できます。 [New Department] チェック ボックスをオンにし、講座および部門の情報を編集し、[Add (FK)] をクリックすると、新しい部門に新しい講座を追加できます。

ナビゲーション プロパティを使用した関連エンティティの追加

この手順では、アプリケーションにコードを追加し、ナビゲーション プロパティを使用して新しい部門および講座を追加できるようにします。

手順

  1. [MainWindow] デザイン画面で、[Add (Nav Prop)] ボタンをダブルクリックします。

    addWithNavPropButton_Click メソッドが分離コード ファイルに追加されます。

  2. addWithNavPropButton_Click メソッドに次のコードを追加します。 新しい講座の [Department] ナビゲーション プロパティを設定すると、新しい講座が部門に関連付けられます。 また、これにより、新しい講座が ObjectContext に追加されます。

    Dim dept As Department
    If newDepartment.IsChecked = True Then
        dept = New Department()
        dept.DepartmentID = Convert.ToInt32(DepartmentIDTextBox.Text)
        dept.Name = NameComboBox.Text
        dept.Budget = Convert.ToInt32(BudgetTextBox.Text)
        dept.StartDate = Convert.ToDateTime(StartDateDatePicker.SelectedDate)
        dept.Administrator = Convert.ToInt32(AdministratorTextBox.Text)
        context.Departments.AddObject(dept)
    Else
        dept = DirectCast(NameComboBox.SelectedItem, Department)
    End If
    
    Dim course As New Course()
    course.CourseID = Convert.ToInt32(CourseIDTextBox.Text)
    course.Title = TitleTextBox.Text
    course.Credits = Convert.ToInt32(CreditsTextBox.Text)
    ' The new course is associated with a department
    ' by setting the Department navigation property.
    ' This also adds the new course to the context.
    course.Department = dept
    context.Courses.AddObject(course)
    context.SaveChanges()
    
    Department dept;
    if (newDepartment.IsChecked == true)
    {
        dept = new Department
        {
            DepartmentID = Convert.ToInt32(departmentIDTextBox.Text),
            Name = nameComboBox.Text,
            Budget = Convert.ToInt32(budgetTextBox.Text),
            StartDate = Convert
                        .ToDateTime(startDateDatePicker.SelectedDate),
            Administrator = Convert.ToInt32(administratorTextBox.Text)
        };
        context.Departments.AddObject(dept);
    }
    else
    {
        dept = (Department)nameComboBox.SelectedItem;
    }
    
    Course course = new Course
    {
        CourseID = Convert.ToInt32(courseIDTextBox.Text),
        Title = titleTextBox.Text,
        Credits = Convert.ToInt32(creditsTextBox.Text),
        // The new course is associated with a department
        // by setting the Department navigation property.
        // This also adds the new course to the context.
        Department = dept
    };
    context.SaveChanges();
    

Crtl+F5 キーを押してプログラムを実行します。 講座情報を編集し、[Add (Nav Prop)] をクリックすると、選択した部門に新しい講座を追加できます。 [New Department] チェック ボックスをオンにし、講座および部門の情報を編集し、[Add (Nav Prop)] をクリックすると、新しい部門に新しい講座を追加できます。

参照

処理手順

方法: 新しい .edmx ファイルを作成する (Entity Data Model ツール)

その他のリソース

Working with Foreign Keys (Entity Framework)