チュートリアル : 型プロバイダーおよびエンティティを使用した SQL データベースへのアクセス (F#)

F# 3.0 のこのチュートリアルでは、ADO.NET エンティティ データ モデルに基づいて SQL データベースの型指定されたデータにアクセスする方法を示します。このチュートリアルでは、SQL データベースで使用するために F# SqlEntityConnection 型プロバイダーを設定する方法、データに対してクエリを作成する方法、データベースでストアド プロシージャを呼び出す方法、いくつかの ADO.NET Entity Framework 型とメソッドを使用してデータベースを更新する方法を説明します。

このチュートリアルでは以下の作業について説明します。このチュートリアルを正しく行うには、これらの作業を順に行ってください。

  • School データベースの作成.

  • F# プロジェクトの作成と構成.

  • 型プロバイダーの構成とエンティティ データ モデルへの接続.

  • データベースの照会.

  • データベースの更新

必須コンポーネント

これらの手順を完了するには、データベースを作成できる、SQL Server を実行中のサーバーにアクセスできる必要があります。

School データベースの作成

SQL Server を実行している、管理者アクセス権を持つ任意のサーバー上に School データベースを作成することも、LocalDB を使用することもできます。

School データベースを作成するには

  1. サーバー エクスプローラーで、[データ接続] ノードのショートカット メニューを開いて、[接続の追加] をクリックします。

    [接続の追加] ダイアログ ボックスが表示されます。

  2. [サーバー名] ボックスに、管理者アクセス権を持つ SQL Server のインスタンス名を指定するか、サーバーにアクセスできない場合は「(localdb\v11.0)」と指定します。

    SQL Server Express LocalDB は、開発およびテスト用の軽量のデータベース サーバーをコンピューターに提供します。LocalDB の詳細については、「チュートリアル: LocalDB データベースの作成」を参照してください。

    新しいノードが、サーバー エクスプローラー[データ接続] の下に作成されます。

  3. 新しい接続ノードのショートカット メニューを開き、[新しいクエリ] を選択します。

  4. Microsoft の Web サイトで「School サンプル データベースの作成」を開き、Student データベースを作成するデータベース スクリプトをコピーしてエディター ウィンドウに貼り付けます。

    このチュートリアルの次の手順は、チュートリアル「ADO.NET Entity Data Model Quickstart」に基づいています。

F# プロジェクトの作成と構成

この手順では、プロジェクトを作成し、型プロバイダーを使用するようにそのプロジェクトを設定します。

F# プロジェクトを作成および構成するには

  1. 前のプロジェクトを閉じ、別のプロジェクトを作成して「SchoolEDM」という名前を付けます。

  2. ソリューション エクスプローラーで、[参照] のショートカット メニューを開き、[参照の追加] をクリックします。

  3. [フレームワーク] ノードを選択し、[フレームワーク] の一覧から System.Data、System.Data.Entity、および System.Data.Linq を選択します。

  4. [拡張] ノードを選択し、FSharp.Data.TypeProviders アセンブリへの参照を追加し、[OK] をクリックしてダイアログ ボックスを閉じます。

  5. 次のコードを追加して、内部モジュールを定義し、適切な名前空間を開きます。型プロバイダーは、プライベートまたは内部名前空間にのみ型を挿入できます。

    module internal SchoolEDM
    
    open System.Data.Linq
    open System.Data.Entity
    open Microsoft.FSharp.Data.TypeProviders
    
  6. このチュートリアルのコードをコンパイル済みプログラムではなくスクリプトとして対話形式で実行するには、プロジェクト ノードのショートカット メニューを開き、[新しい項目の追加] を選択し、F# スクリプト ファイルを追加して、各手順のコードをスクリプトに追加します。アセンブリ参照を読み込むには、次の行を追加します。

    #r "System.Data.Entity.dll"
    #r "FSharp.Data.TypeProviders.dll"
    #r "System.Data.Linq.dll"
    
  7. コードの各ブロックを強調表示して追加し、Alt キーを押しながら Enter キーを押して F# Interactive で実行します。

型プロバイダーの構成とエンティティ データ モデルへの接続

この手順では、データ接続を使用して型プロバイダーを設定し、データを処理できるデータ コンテキストを取得します。

型プロバイダーを構成してエンティティ データ モデルに接続するには

  1. 前に作成したエンティティ データ モデルに基づいて F# の型を生成する SqlEntityConnection 型プロバイダーを構成する次のコードを入力します。完全な EDMX 接続文字列の代わりに、SQL 接続文字列のみを使用します。

    type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true",
                                                        Pluralize = true>
     >
    

    この操作により、前に作成したデータベース接続を使用して型プロバイダーを設定します。MultipleActiveResultSets プロパティは、ADO.NET Entity Framework を使用する際に必要です。これは、このプロパティにより、1 つの接続でデータベースに対して複数のコマンドを非同期で実行できるようになるためです。この状況は ADO.NET Entity Framework コードで頻繁に発生します。詳細については、「複数のアクティブな結果セット (MARS) の使用」を参照してください。

  2. データ コンテキストを取得します。これは、プロパティとしてデータベース テーブルを含み、メソッドとしてデータベース ストアド プロシージャと関数を含むオブジェクトです。

    let context = EntityConnection.GetDataContext()
    

データベースの照会

この手順では、F# クエリ式を使用してデータベースに対してさまざまなクエリを実行します。

データを照会するには

  • エンティティ データ モデルからデータを照会する次のコードを入力します。データベース テーブル Course を Courses に、Person を People に変更する Pluralize = true の効果に注目してください。

    query { for course in context.Courses do
            select course }
    |> Seq.iter (fun course -> printfn "%s" course.Title)
    
    query { for person in context.People do
            select person }
    |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName)
    
    // Add a where clause to filter results.
    query { for course in context.Courses do
            where (course.DepartmentID = 1)
            select course }
    |> Seq.iter (fun course -> printfn "%s" course.Title)
    
    // Join two tables.
    query { for course in context.Courses do
            join dept in context.Departments on (course.DepartmentID = dept.DepartmentID)
            select (course, dept.Name) }
    |> Seq.iter (fun (course, deptName) -> printfn "%s %s" course.Title deptName)
    

データベースの更新

データベースを更新するには、Entity Framework のクラスとメソッドを使用します。SQLEntityConnection 型プロバイダーでは 2 種類のデータ コンテキストを使用できます。最初の ServiceTypes.SimpleDataContextTypes.EntityContainer はデータベース テーブルと列を表す指定されたプロパティのみを含む簡易データ コンテキストです。2 番目の完全データ コンテキストは Entity Framework クラス ObjectContext のインスタンスで、これはデータベースに行を追加するメソッド AddObject を含んでいます。Entity Framework は、テーブルとそれらのリレーションシップを認識するため、データベースの一貫性が強化されます。

データベースを更新するには

  1. プログラムに次のコードを追加します。この例では、2 つのオブジェクトとそのリレーションシップを追加し、インストラクターとオフィス割り当てを追加します。テーブル OfficeAssignments には InstructorID 列が含まれています。この列は Person テーブルの PersonID 列を参照します。

    // The full data context
    let fullContext = context.DataContext
    
    // A helper function.
    let nullable value = new System.Nullable<_>(value)
    
    let addInstructor(lastName, firstName, hireDate, office) =
        let hireDate = DateTime.Parse(hireDate)
        let newPerson = new EntityConnection.ServiceTypes.Person(LastName = lastName,
                                                    FirstName = firstName,
                                                    HireDate = nullable hireDate)
        fullContext.AddObject("People", newPerson)
        let newOffice = new EntityConnection.ServiceTypes.OfficeAssignment(Location = office)
        fullContext.AddObject("OfficeAssignments", newOffice)
        fullContext.CommandTimeout <- nullable 1000
        fullContext.SaveChanges() |> printfn "Saved changes: %d object(s) modified."
    
    addInstructor("Parker", "Darren", "1/1/1998", "41/3720")
    

    SaveChanges を呼び出すまで、データベースの変更は行われません。

  2. ここで、追加したオブジェクトを削除して、データベースを以前の状態に復元します。

    let deleteInstructor(lastName, firstName) =
            query {
                for person in context.People do
                where (person.FirstName = firstName &&
                        person.LastName = lastName)
                select person
            }
            |> Seq.iter (fun person->
                query {
                    for officeAssignment in context.OfficeAssignments do
                    where (officeAssignment.Person.PersonID = person.PersonID)
                    select officeAssignment }
                |> Seq.iter (fun officeAssignment -> fullContext.DeleteObject(officeAssignment))
    
                fullContext.DeleteObject(person))
    
            // The call to SaveChanges should be outside of any iteration on the queries.
            fullContext.SaveChanges() |> printfn "Saved changed: %d object(s) modified."
    
    deleteInstructor("Parker", "Darren")
    
    Caution メモ注意

    クエリ式を使用する際は、クエリには遅延評価が適用されることに注意してください。したがって、データベースは、各クエリ式の後にあるラムダ式ブロックなどのチェーン評価中は読み取り用に開いています。明示的または暗黙的にトランザクションを使用するデータベース操作は、読み取り操作の完了後に行われます。

次の手順

クエリ式 (F#) で使用できるクエリ演算子を確認して他のクエリ オプションを検討し、ADO.NET Entity Framework も確認して、この型プロバイダーを使用する際にどの機能を使用できるかを理解します。

参照

処理手順

チュートリアル : EDMX スキーマ ファイルからの F# 型の生成 (F#)

関連項目

SqlEntityConnection 型プロバイダー (F#)

その他の技術情報

型プロバイダー

ADO.NET Entity Framework

.edmx File Overview (Entity Framework)

Edm Generator (EdmGen.exe)