MSDN マガジン > Home > 発行物 > 2008 > July >  ADO.NET : Entity Framework で柔軟なデータ モデリングを実現する
ADO.NET
Entity Framework で柔軟なデータ モデリングを実現する
Elisa Flasko

この記事では、次の内容について説明します。
  • Entity Framework の背後にある考え方
  • Entity Data Model
  • クエリ、マッピング、および n 層開発
この記事では、次のテクノロジを使用しています。
ADO.NET、LINQ、Entity Framework

コードのダウンロード : EntityFramework2008_07.exe (6,602 KB)
オンラインでのコードの参照

ADO.NET Entity Framework を世に送り出す日が近づいてきました。2006 年に ADO.NET vNext として初めて紹介されたこのフレームワークは、間もなく Visual Studio® 2008 SP1 のリリースにより、晴れの舞台に登場します。マイクロソフトでは、何年にもわたって同様の製品の開発に挑みながら失敗を重ねた後、Visual Studio 2008 で部分的にオブジェクト リレーショナル マッピング (ORM) 空間に適応する 2 つのテクノロジをリリースしました。それが、LINQ to SQL と ADO.NET Entity Framework です。これらのテクノロジの市場での採用に伴い、開発者は現在、それがどのように開発され、そしてマイクロソフトが次にどこに進むのかを知りたがっています。また、これらのテクノロジの裏側に何があり、Entity Framework は市場の他の ORM テクノロジと何が違い、そしてマイクロソフトがこれらのテクノロジの将来に向けて何を投資しているのかにも関心を向けています。
Visual Studio 2008 の最初のリリース以降、LINQ to SQL に焦点を合わせた記事や、どのテクノロジを使用すればよいかについて述べた記事が、数多く書かれています (msdn.microsoft.com/data を参照)。ここでは、Entity Framework に焦点を当て、開発中にどのような選択がどのような理由で行われたのかを詳しく理解できるようにしています。
ADO.NET Entity Framework を実際に背後で支えているのは、Peter Chen 博士の Entity Relationship (ER) モデルに基づく Microsoft® Entity Data Model (EDM) です。また、Entity Framework を市場の他の ORM 型テクノロジから差別化する最も大きな要因となっているのも、この EDM です。EDM は ER モデルに基づいて構築され、エントリおよびリレーションシップの概念を保持しながら、モデルの抽象レベルを論理モデルよりも 1 段階高めています。

新たなデータ モデルが必要な理由
それでは、なぜ別のモデルが必要だったのでしょうか。企業で扱うデータの量が増えると共に、それらのデータを処理するアプリケーションを理解し、開発することは、非常に困難になってきました。データベース スキーマはストレージに関する問題 (データの整合性、パフォーマンス、管理など) を考慮しながら設計され、必ずしも理解しやすいものではありません。また、多くの場合、これらのスキーマはアプリケーションの構造と合っていないため、開発や保守がさらに複雑になっています。
構築するアプリケーションからデータの構造を分離するカスタム ソリューションは、一般的に使用されていました。しかし残念なことに、利用するカスタム ソリューション、さまざまなアプローチ、およびデータのモデリングに必要な手順が、すべてアプリケーションごとに異なっていたため、問題は大きくなる一方でした。業界全体にわたって、ストアの論理モデルから明確に分離できるアプリケーション レベルのドメイン モデルの定義方法、およびそのようなモデルに対する開発方法が、絶えず求められていました。そこで登場したのが、Entity Framework です。
EDM (図 1 のサンプルを参照) では、データを格納する方法に合わせるのではなく、組織がデータについて考え、それを使用する方法に合わせて、ドメイン モデルを定義できます。また、EDM は、マイクロソフト内の一連の開発者テクノロジおよびサーバー テクノロジに共通のコア データ モデルとすることを第一の目標として開発されました。
図 1 ブログ データベースに対する Entity Data Model のサンプル (クリックすると拡大画像が表示されます)
1 つのコア データ モデルを使用することで、アプリケーションの保守が単純になります。この目標が実現されれば、EDM は、ADO.NET Entity Framework で構築されたカスタム アプリケーションに対してだけでなく、レポートおよび視覚化アプリケーション、イントラネット ポータル アプリケーション、またはワークフロー アプリケーションへの入力としても、モデルを定義できるようになります。
ER モデルと同様に、EDM では 2 つの主要な概念を使用します。1 つはエンティティ (もの) であり、もう 1 つはそれらのエンティティ間のリレーションシップ (関連付け) です。エンティティおよび関連付けのインスタンスの格納や、それらのインスタンスに対する集合演算のクロージャを考える場合には、集合の概念も必要となります。したがって、最終的な形として、エンティティは EntitySets 内に含まれ、関連付けは AssociationSets 内に含まれます。
EDM で定義される最後の構造的概念は、EntityContainer の概念です。これは、前述のインスタンスおよびリレーションシップの集合に対してクロージャを定義する概念です。これらの単純な概念を併せて使用することで、開発者は、永続化層に対して、およびアプリケーション自体で使用されるクラスに対してマッピングできる、ドメイン モデルを定義できます。(現在はそうなっていますが、EDM の永続化層は必ずしもリレーショナルでなくてもよいことに注意してください。)
EDM で定義される各エンティティ型には、2 つの異なる種類のメンバを含めることができます。エンティティを定義するプロパティ (データベースの列に相当) と、エンティティ型が含まれるリレーションシップのナビゲーションを可能にするナビゲーション プロパティ (データベースで一般に外部キーと呼ばれるもの) です。これらに加えて、各エンティティ型には、個別の ID またはキーが必要です。図 2 の XML 断片では、BlogPost というエンティティ型を記述しています。
<EntityType Name="BlogPost">
   <Key>
      <PropertyRef Name="BlogPostID" />
   </Key>
   <Property Name="BlogPostID" Type="Int32" Nullable="false" />
   <Property Name="BlogEntry" Type="String" Nullable="false" MaxLength="Max" 
             Unicode="true" FixedLength="false" />
   <Property Name="BlogDate" Type="DateTime" Nullable="false" />
   <Property Name="BlogTitle" Type="String" Nullable="false" MaxLength="500" 
             Unicode="true" FixedLength="false" />
   <Property Name="BlogType" Type="Int32" Nullable="false" />
   <Property Name="CityVisited" Type="String" MaxLength="200"
             Unicode="true" FixedLength="false" />
   <Property Name="CountryVisited" Type="String" MaxLength="200" Unicode="true" 
             FixedLength="false" />
   <Property Name="DateVisited" Type="DateTime" />

   <NavigationProperty Name="Blog" Relationship=
                       "MyTravelPostModel.FK_BlogPosts_Blogs"
                       FromRole="BlogPosts" ToRole="Blogs" />
   <NavigationProperty Name="Pictures" Relationship=
                       "MyTravelPostModel.FK_Pictures_BlogPosts"
                       FromRole="BlogPosts" ToRole="Pictures" />
   <NavigationProperty Name="Comments" Relationship=
                       "MyTravelPostModel.BlogComments"
                       FromRole="BlogPosts" ToRole="Comments" />
</EntityType>
エンティティ型のプロパティには、プリミティブ型または複合型を使用できますが (図 3 を参照)、Entity Framework 1.0 では、他のエンティティ型を使用したり、プリミティブ型や複合型のコレクションを使用したりはできません。エンティティ型のキーは、これらのプロパティのサブセットで構成されます。ナビゲーション プロパティを使用すると、1 つのエンティティから他のエンティティへとリレーションシップをナビゲーションできます。
<ComplexType Name="Address">
    <Property Name="StreetAddress"
              Type="String" MaxLength="50" />
    <Property Name="Address2"
              Type="String" MaxLength="50" />
    <Property Name="City"
              Type="String" MaxLength="50" />
    <Property Name="Region"
              Type="String" MaxLength="50" />
    <Property Name="PostalCode"
              Type="String" MaxLength="50" />
    <Property Name="Country"
              Type="String" MaxLength="50" />
</ComplexType>
前述のように、リレーションシップは、そのリレーションシップに含まれる各エンティティ型のナビゲーション プロパティとして公開できます。リレーションシップ自体は、EDM の標準要素であり、EDM では関連付けとして明示的に定義されています。
<Association Name="FK_Friends_People">
   <End Role="People" Type="MyTravelPostModel.Person" Multiplicity="1" />
   <End Role="Friends" Type="MyTravelPostModel.Friend" Multiplicity="*" />
   <ReferentialConstraint>
      <Principal Role="People">
         <PropertyRef Name="PersonID" />
      </Principal>
      <Dependent Role="Friends">
         <PropertyRef Name="PrimaryPersonID" />
      </Dependent>
   </ReferentialConstraint>
</Association>
それでは、手短かに言って、私たちはそもそもなぜ新しいデータ モデリング テクノロジを作成したのでしょうか。EDM 以前にもいくつかのデータ モデリング テクノロジまたは言語が存在していましたが、マイクロソフトが実現を目指していた第一目標を満足できるものはなく、多く使用されていた Entity Relationship モデルを実行可能にするために役立つものもありませんでした。開発チームでは、膨大な数の既存のデータ モデリング テクノロジを調査しましたが、そのどれもが特定の問題領域に固有または焦点を絞っている度合いがかなり高いことがわかりました。そのため、これらの目標を満足させて、一連の開発者テクノロジおよびサーバー テクノロジに共通のコア データ モデルとして真に使用可能なモデルを作成するために、EDM の開発を始めたのです。

EDM を XML で記述する理由
多くの検討を重ねた結果、EDM の最初のシリアル表現として XML が選択されました。適切に定義された XML 形式を使用することにより、開発者およびサード パーティは、XML ファイル (またはリソース) を生成するか、または動的に生成された XML 表現から読み込むことで、XML 形式への変換や Entity Framework のメタデータ ランタイムへの読み込みを実現できます。ただし、EDM の表現はそれ以外にも作成可能であり、製品がリリースを重ねる過程で他の表現が導入される可能性もあります。
現在の EDM の文法は、製品に付属の XML スキーマ定義言語 (XSD) で定義されています。ただし、ほとんどの開発者が XML を手作業で開発することは想定していません。その代わりに、Visual Studio で提供されるツールを使用します。その一方で、開発チームでは、ドメイン固有言語 (DSL) への関心や、EDM モデルに対する別の永続化メカニズム (データベースが一般的) への関心も耳にしており、将来のリリースでの拡張オプションも評価中です。

新しいクエリ言語はだれのために必要か
EDM の開発に関する最後の疑問は、なぜ新しいクエリ言語を作成したのかということです。どうして既存の言語を使用してはいけないのでしょうか。その答えは、EDM をもう少し詳しく見ていく中で、明らかになります。
ここまで、EDM が作成された理由と、EDM で使用される各種のコンストラクト、およびこのモデルが Entity Relationship モデルから派生しているという事実について説明しました。基になるデータ ストアに明確にマッピングできるだけでなく、プログラミングに適したアプリケーション レベルのドメイン モデルを表現できるようなモデルを作成する中で、EDM は継承やポリモーフィズムなどの概念をモデリングできる必要がありました。現在のリレーショナル クエリ言語は、継承に基づくクエリや、リレーションシップのナビゲーション、およびポリモーフィズムの結果を返すことをサポートしていないため、この要件を満たすために新しいクエリ言語が必要となりました。
このようにして生まれた Entity SQL (ESQL) は、以前の SQL 言語ではサポートされていない概念に基づいたクエリ機能を追加で備えた、新しい SQL 言語です。EDM がデータベースで使用されているリレーショナル モデルを拡張するのとほとんど同じ方法で、ESQL は既存の SQL 言語を拡張します。また、ESQL はどの特定のバックエンド データベースの構文にも結び付けられていないため、対象となるバックエンド データベースにかかわらず、クエリやアプリケーションを一度だけ記述すれば済みます。次の例は、1 つ以上のブログ ポストを含んでいるすべてのブログと、関連付けられた Person (このモデルの場合はブログ所有者) を取得する、単純な ESQL クエリです。
select c, c.Person 
  from travelEntitiesGeneral.Blogs as c 
  where c.BlogPosts.Count > 0

EDM を実装する
ADO.NET Entity Framework は、ADO.NET の進化形であり、EDM の最初の具体的な実装として、リレーショナル データベースに対する開発時に、より高い抽象レベルを提供します。バージョン 1.0 では、開発チームは単なる ORM よりもむしろプラットフォームの基盤の構築に重点を置きました。それによって開発者は、非常に柔軟性の高いマッピングと、基になるストアからの逸脱をかなりの程度許容できる能力を備えた、概念モデルまたはオブジェクト モデルを利用できるようになっています。
この高いレベルの柔軟性と、基になるレベルからの逸脱とが、データベースとアプリケーションをそれぞれ別々に進化させるための鍵となります。データベース スキーマに変更が加えられても、アプリケーションは Entity Framework によってその変更から隔離されているため、多くの場合、アプリケーションを部分的に書き換える必要はありません。その代わり、変更を反映する必要がある場合は、単純にマッピング ファイルを更新すれば済みます。
ADO.NET プラットフォームの進化を開始させるには、既存の ADO.NET 2.0 プロバイダ モデル上に Entity Framework を構築し、新しい Entity Framework および ADO.NET 3.5 機能をサポートするよう既存のプロバイダを少しだけ更新します。既存の ADO.NET プロバイダ モデル上に実装することを選択したのは、開発者コミュニティで親しまれているプロバイダ モデルをそのまま利用できるようにするためです。
このアーキテクチャを図 4 に示します。使用可能なスキーマには、概念スキーマ定義言語 (CSDL)、マッピング スキーマ言語 (MSL)、およびストア スキーマ定義言語 (SSDL) が含まれることが、この図からわかります。また、Entity Framework には、正規コマンド ツリー (CCT) をサポートする更新された SqlClient データ プロバイダが含まれていることにも注意してください。
図 4 ADO.NET Entity Framework のアーキテクチャ (クリックすると拡大画像が表示されます)

EntityClient
次に Entity Framework は、これらの ADO.NET 3.5 プロバイダ上に、新しい ADO.NET プロバイダである EntityClient を導入します。EntityClient は、皆さんが慣れ親しんでいる ADO.NET プロバイダと非常によく似ており、開発者が標準の Connection、Command、および DataReader オブジェクトを使用してクエリを EDM 式に実行できるよう、第 1 段階の抽象を提供します。また、EDM で定義されたドメイン モデルを基になるリレーショナル データベース スキーマにマッピングするために必要な、クライアント ビュー エンジンも追加しています。EntityClient は、開発者が必要に応じて、概念的スキーマを表現するクラスを生成しなくても、ESQL クエリ文字列を使用して行および列の形式でエンティティを操作することを可能にします。
図 5 での EntityClient の使い方を見れば、ESQL クエリ文字列を取得して EntityCommand が作成され、EDM に対してそのコマンドが実行されていることがわかるでしょう。EntityCommand の一部として提供されたクエリ テキストが分析され、CCT が作成されます。
using (EntityConnection conn = new 
         EntityConnection("name=travelEntitiesGeneral"))
{
      conn.Open();
      EntityCommand cmd = conn.CreateCommand();
      cmd.CommandText = @"select c.BlogID 
         from travelEntitiesGeneral.Blogs as c 
         where c.BlogPosts.Count > 0";
      EntityDataReader reader = 
         cmd.ExecuteReader(CommandBehavior.SequentialAccess);
      while (reader.Read())
      {
         Console.WriteLine("BlogID = {0}", reader["BlogID"]);
      }
     conn.Close();
}
この最初の段階では、コマンド ツリーはまだ EDM 式に表現されています。クライアント ビュー エンジンでは、データベース システムの具体化されたビューの理論を利用していますが、これらの理論をデータ アクセス層に適用しています。ツリーにマッピング変換を適用することで、基になる論理ストレージ モデルについては同じ動作を表現しているツリーを生成しながら、リレーションシップ、継承、ポリモーフィズムなどの非リレーショナルな概念を除外します。この新しく変換されたツリーが ADO.NET 3.5 プロバイダ サービスに渡され、これらのサービスは、基になるストアに対してネイティブ SQL をカプセル化する DbCommand を返します。このコマンドが実行され、スタック経由で結果が返されて反映されます。

EDM と論理データベース スキーマの間で変換を行うためにクライアント ビュー エンジンで使用されるマッピングを定義する際には、いくつかの異なるオプションがあります。このマッピングは、宣言型の XML 文法であるマッピング仕様言語 (MSL) を使用して指定できます。これは、XML をハンド コーディングするか、または Visual Studio に含まれるエンティティ マッピング ツールを使用して作成できます (図 6 を参照)。
<EntitySetMapping Name="BlogPosts">
   <EntityTypeMapping TypeName="IsTypeOf(MyTravelPostModel.BlogPost)">
      <MappingFragment StoreEntitySet="BlogPosts">
         <ScalarProperty Name="BlogPostID" ColumnName="BlogPostID" />
         <ScalarProperty Name="BlogEntry" ColumnName="BlogEntry" />
         <ScalarProperty Name="BlogDate" ColumnName="BlogDate" />
         <ScalarProperty Name="BlogTitle" ColumnName="BlogTitle" />
         <ScalarProperty Name="BlogType" ColumnName="BlogType" />
         <ScalarProperty Name="CityVisited" ColumnName="CityVisited" />
         <ScalarProperty Name="CountryVisited" 
                         ColumnName="CountryVisited" />
         <ScalarProperty Name="DateVisited" ColumnName="DateVisited" />
      </MappingFragment>
   </EntityTypeMapping>
</EntitySetMapping>
MSL がコンパイルされると、Entity Framework は必要なクエリを生成してビューを更新することができます。クライアント ビュー エンジンではそれらを使用して、EDM で定義されたクエリから論理ストレージ スキーマへの変換を実現します。
マッピングまたはマッピングの一部を表現するための他のオプションとして、ESQL クエリを使用する方法もあります。その場合、開発者が ESQL を使用してクエリ ビューを記述する際には、インフラストラクチャでの要件として、付随する Create、Update、および Delete マッピングもマッピング指定に含めて定義する必要があります。これは必須です。なぜなら、クエリ ビューで ESQL の能力を活用できる場合、1 つの有効な更新ビューが存在しないようなビューを定義することが可能なため、マッピング インフラストラクチャがクエリ ビューに対して対応する更新ビューを生成できないからです。

Object Services
EntityClient によって返される型指定のないデータ レコードに対してではなく、オブジェクトに対して開発できるようにするために、Entity Framework では、EntityClient プロバイダ上に新たな抽象のセットが追加されます。これは、一般に ORM と見なされている層です。この層では、データ モデルに定義されている型の CLR インスタンスが生成され、開発者は LINQ または ESQL を使用してこれらのオブジェクトに対してクエリを実行できるようになります。また、この層は、Entity Framework の中で、市場で各種の ORM テクノロジを調査している開発者を最初にひきつける役割も担っています。
図 1 で見たように、Object Services 層の上位機能は、アプリケーションから ESQL または LINQ クエリを取得して、下層の EntityClient にクエリ式を渡し、IEnumerable<T> を返すことです。ただし、もう少し深く見てみると、Object Services 層の中核には ObjectContext があり、これはアプリケーションと基になるデータ ストアとの間の対話セッションを表しています。
ObjectContext は、開発者がエンティティのインスタンスに対してクエリ、追加、および削除を実行するときや、データベースに新しい状態を返して保存するときに使用する、主要なコンストラクトです。ObjectContext の作成、および ObjectContext を使用したエンティティのクエリ、操作、および SaveChanges のコードを図 7 に示します。この例では、クエリ言語として ESQL を使用しています。
using (ObjectContext context = new ObjectContext("name=travelEntities"))
    {
        //--- create a query for customers
        ObjectQuery<Person> personQuery = context.CreateQuery<Person>(
                     @"select value c from travelEntitiesGeneral.People 
                     as c where c.PersonID == 1");
        //--- by enumerating the query will be implicitly executed
        //--- against the store and you can now work with an
        //--- IEnumerable<Customer>
        foreach (Person c in personQuery)
        {
            //--- dereference anything you like from Customer
            Console.WriteLine(c.PersonID + ": " + c.Name);
            c.Name = "New Name";
        }
        try
        {
            context.SaveChanges();
        }
        catch (OptimisticConcurrencyException opt)
        {
            // catching this exception allows you to 
            // refresh travelEntities with either store/client wins
            // project the travelEntities into this failed travelEntities.
            var failedEntities = from e3 in opt.StateEntries
                                 select new { e3.Entity };

            // Note: in future you should be able to just pass 
            // the opt.StateEntities  
            // in to refresh.
            context.Refresh(RefreshMode.ClientWins, failedEntities.ToList());
            context.SaveChanges();
        }
    } 
メモリ内でオブジェクトに加えられた変更を追跡するプロセス、およびそれらの変更をデータベースに返して保存するプロセスは、Object Services の使用によって単純化されます。Object Services では、ObjectStateManager を利用して、メモリ内のインスタンスの現在の状態だけでなく、ストアから取得された時点での各インスタンスの初期状態も追跡するため、Entity Framework は、データをデータベースに返すときにオプティミスティックな同時実行を適用できます。追跡された変更は簡単に保存でき、ObjectContext に対して SaveChanges メソッドが呼び出されたときに、データ ストアに返して反映させることができます。
ここまで、ObjectContext に関する一般的な事項を述べ、基本となる ObjectContext の使用例を示してきました。これは多くの場合、EDM モデルを消費する動的なツールやアプリケーションが存在するシナリオで使用されます。ただし、開発環境として Visual Studio を使用する場合には、厳密に型指定された ObjectContext が持つ追加の利点として、対象の EDM に固有である可能性がある機能を公開するようなプロパティとメソッドを追加できます。
厳密に型指定された ObjectContext を使用して構築されたクエリを図 8 に示します。この例では、クエリ言語として LINQ が使用されています。厳密に型指定された ObjectContext を使用すると、プロパティが EntitySet ごとに公開されるため、プロパティを見つけやすくなります。たとえば、travelEntities.CreateQuery<BlogPost>("travelEntitiesGeneral.BlogPosts") の代わりに travelEntities.BlogPosts が使用されます。
using (MyTravelPostEntities travelEntities = new MyTravelPostEntities())
{
    // get the latest blog post, with the comments and the people
    // I'm querying for all the blog posts that are related to this blog.
    // I want to include the comments and the people who wrote the
    // comments.
    // I also want only the most recent posting.
    // Note: Since we use the EntityKey that is put on the EntityReference
    // we can either do a tracking query or use span.
    BlogPost post = (from bp in 
        travelEntities.BlogPosts
                              .Include("Comments.Person")
                              .Include("Blog")
                     where bp.Blog.BlogID == requestedBlog.BlogID
                     orderby bp.BlogDate descending
                     select bp).First();
    return post;
} 
LINQ to Entities は Object Services の上にある比較的薄い層と考えることができ、文字列ベースのクエリの代わりに、プログラミング言語内で直接クエリ機能を提供します (図 8 を参照)。ここでは、ObjectQuery クラスが IQueryable を実装して、LINQ の式ツリーを取得可能にし、Object Services が EntityClient プロバイダに ESQL クエリを渡すのと同じ方法で、Entity Framework を通してクエリを CCT クエリ式として渡しています。
Entity Framework による n 層開発
n 層開発に完全に対応することは私たちの第一の目的ではありませんが、Entity Framework での開発に関する興味深いシナリオの 1 つとして、それに触れておくことにします。バージョン 1.0 では、Entity Framework はいくつかの主要なシナリオで n 層開発をサポートしています。これには、ADO.NET データ サービスの使用、またはエンティティをシリアル化して ObjectContext にアタッチおよびデタッチする能力による Windows® Communication Foundation (WCF) の使用が含まれます。これらは明らかに、n 層開発に対する唯一のアプローチではありませんが、開発チームが V1 で焦点を当てることを選んだソリューションであり、V2 以降では、よりデータセットに似た体験など、新たなシナリオが追加されています。図 9 に、これらの内容を示します。
static Uri baseService = new 
   Uri("http://localhost:17338/MyTravelPostService.svc");
MyPeople2Entities context = new MyPeople2Entities(baseService); 
    // get the comment that is being marked for deletion
    // and get the view state blog post.
BlogPost post = (BlogPost)ViewState["BlogPost"];

    // move the comment to the deleted comment selection. 
Comment deletedComment = post.Comments[e.RowIndex];

    // call the DeleteComment service
context.AttachTo("Comments", deletedComment);
context.DeleteObject(deletedComment);
DataServiceResponse r = context.SaveChanges();

    // reload page so that F5, refresh doesn't update all this data.
ReloadPage();
ADO.NET データ サービスは、Representational State Transfer (REST) アーキテクチャ スタイル (各リソースがシステム内の "名詞"、つまり Uniform Resource Identifier (URI) で一意に扱えるものを表す) の具体的な実現であり、任意の IQueryable 実装上での n 層アプリケーション開発を可能にします。ADO.NET データ サービスでは、インスタンスに対する単なるクエリ以上のことを、ネットワーク経由で実行できます。ADO.NET データ サービスは、Create、Read、Update、および Delete に対する各種の HTTP 動詞をサポートし、開発者がソリューションを実装する際に役立つクライアント側抽象を提供します。
n 層シナリオの第 2 のオプションは、エンティティをシリアル化して ObjectContext にアタッチおよびデタッチする能力を利用し、Entity Framework で WCF を使用することです。図 10 に、このシナリオで ObjectContext にアタッチする方法を示します。
// the creation of the travel MyTravelPostEntities opens the connection 
// and sets up all the metadata information automatically for you.
using (MyTravelPostEntities travelEntities = new MyTravelPostEntities())
{
    // attach the comment and delete.
    travelEntities.Attach(deleteComment);

    // call delete on the object
    travelEntities.DeleteObject(deleteComment);

    try
    {
       travelEntities.SaveChanges();
    }
    catch (OptimisticConcurrencyException opt)
    {
      // catching this exception allows you to 
      // refresh travelEntities with either store/client wins
      // project the travelEntities into this failed travelEntities.
      var failedEntities = from e3 in opt.StateEntries
                           select new { e3.Entity };

     travelEntities.Refresh(RefreshMode.ClientWins, failedEntities.ToList());
     travelEntities.SaveChanges();
    }
}
既定では、Visual Studio または edmgen.exe (Entity Framework に付属するコマンドライン ツール) を使用して EDM から生成される任意の CLR クラスは、XML シリアル化およびバイナリ シリアル化が可能であり、既定の属性が DataMembers であるナビゲーション プロパティを持ったデータ コントラクトです。それにより、ASMX Web サービスの作成や、Entity インスタンスをビュー ステートまたは WCF サービスで使用することが可能になります。
ほとんどの ORM と同様に、現時点で Entity Framework は、データ操作言語 (DML) での作成、更新、または削除操作をサポートしていません。変更はメモリ内のオブジェクトに適用する必要があり、永続化するグラフ全体を構築するためには、データベースへのラウンドトリップが何回か必要になる可能性があります。
これを避けることができる方法の 1 つは、ObjectContext によって提供されるアタッチ機能を使用することです。Attach を使用すると、Entity が既に存在すること、および操作のセットをメモリ内で実行してから変更を反映する必要があることを、インフラストラクチャに指示できます。Entity Framework を使用した n 層開発の詳細については、MSDN® ライブラリを検索してください。近いうちに内容が追加される予定です。

単なる ORM の一種か
これまで、Entity Framework は多くの人々から、単に市場に出ている ORM の 1 つであると考えられており、製品の最初のバージョンを単純に見る限り、それは理解できることです。その方向について言えば、これまでに製品に搭載された機能の多くにより、ORM が取り組み始めたシナリオの中心的な部分は実現されています。ただし、これまで行われた多くの分析では、市場内の他のいくつかの ORM で可能な要素を Entity Framework が必ずしもすべての場合にカバーしていないことが指摘されており、それは妥当な見解と言えます。
マイクロソフトがこの領域で行っている投資は、従来の ORM 製品の投資をはるかに上回るよう意図されており、これから簡単に述べるように、Entity Framework は、EDM に関する幅広い戦略における最初の一歩なのです。この記事の冒頭で述べたように、EDM は単なる Entity Framework や従来の ORM の世界を飛び越えて適用できる、より高いレベルのドメイン モデルを作成します。Microsoft .NET Framework、Visual Studio、SQL Server®、および他のマイクロソフト テクノロジの次のいくつかのリリースで、EDM の採用が段階的に増えていくでしょう。
そのような見通しと、EDM の行く先についての全体的ビジョンこそが、この記事で述べてきた製品に関する決定事項の多くに見られたように、最も大きな影響を与えてきた要素です。多くの決定が、Reporting Services や Analysis Services などのテクノロジの採用を実現するという明確な意図に基づいて行われました。それにより、一般的な一貫したドメイン モデルでサービスを提供できるため、顧客に対して強力な利点がもたらされます。
Visual Studio 2008 SP1 では、Entity Framework と共に、このビジョンの最初の実現が ADO.NET データ サービスとしてリリースされます。REST ベースのアプリケーションに対して開発者に魅力的な体験を提供する ADO.NET データ サービスは、メタデータ交換形式として EDM を使用して構築される、(Entity Framework 外部では) 初めてのリリース製品となります。
このリリースに合わせて、マイクロソフトではいくつかの異なる Windows Live™ プロパティのデモを MIX 2008 で行いました。これらのプロパティは、ADO.NET データ サービス プロトコルおよび EDM を使用してデータを公開するものです。同様に、開発チームでは、SQL Server および Visual Studio の次回のリリースに対する計画を開始しており、コアにおける EDM および Entity Framework のエンドツーエンドの開発者体験の向上に向け、日々努力を重ねています。

Elisa Flasko は、マイクロソフトのデータ プログラマビリティ チームのプログラム マネージャであり、ADO.NET、XML、および SQL Server 接続テクノロジを主に担当しています。blogs.msdn.com/elisaj で彼女のブログをご覧いただけます。

Page view tracker