SlideShare uma empresa Scribd logo
1 de 75
Baixar para ler offline
VSUG DAY 2010 Summer
 ADO.NET Entity Framework
 を使いこなそう

福井 厚 ( Twitter: @afukui )
          VSUG運営委員
    Microsoft Certified Architect
     Microsoft Regional Director
    Microsoft MVP for Visual C#
自己紹介

福井 厚 (ふくい あつし)
アバナード株式会社
Group Manager / CTO Architect


Visual Studio User Group 運営委員
Microsoft Certified Architect (MCA)
Microsoft Regional Director
Microsoft MVP for Visual Developer – C#
Blog: http://www.users.gr.jp/blogs/fukui/
Twitter: @afukui
                     VSUG DAY 2010.05.09
突然ですがアンケートを実施




        VSUG DAY 2010.05.09
Agenda

 ADO.NET Entity Frameworkとは
 EDM(Entity Domain Model)とは
 ObjectServicesとクエリ
 オブジェクトの追加、更新、削除
 同時実行制御
 エンティティ状態と変更の追跡
 エンティティの継承と抽象化
 N層アプリと自己追跡エンティティ
 まとめ
            VSUG DAY 2010.05.09
一般的な設計アプローチ

ドメイン モデル、設計モデル、物理モデルの3つに分
割
ドメイン モデル
 対象となるシステムに存在するエンティティとリ
  レーションシップを定義
設計モデル
  外部キー制約を用いながら、エンティティとリレーションシッ
   プをテーブルとして正規化(RDBの場合)
物理モデル
  パーティション分割やインデックス化などのストレージ情報を
   指定することで、特定のデータ エンジンの機能に対応




           VSUG DAY 2010.05.09
開発アプローチ

ドメイン モデル駆動
 概念モデルをストレートにマッピング
 複雑なビジネス ロジック
データベース駆動
 データ中心アプローチ
 既存のDBテーブルの活用
ユーザー インターフェース駆動
 モックアップから開発


          VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
Entity Frameworkとは

 データ指向のソフトウェア アプリケー
 ション開発をサポートする ADO.NET のテ
 クノロジ セット
 データが格納されている、基になるデー
 タベース テーブルや列を意識することな
 く、顧客や顧客の住所など、ドメイン固
 有のオブジェクトおよびプロパティの形
 式でデータを扱うことが可能
 EDM(後述)の実装を提供

                VSUG DAY 2010.05.09
Entity Framework Architecture



                                            Object Services
Entity Domain Model                         ObjectContext
                                            ObjectQuery<T>
                                            Data Class

     CSDL

                                            EntityClient
                                            EntityConnection
     MSL                                    EntityCommand
                                            EntityDataReader



     SSDL




                      VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
EDM(Entity Domain Model)とは

 格納される形式に関係なく、データ構造を記述
 する一連の概念
 ストレージ スキーマに依存しないエンティティ
 とリレーションシップでデータ構造を記述
 エンティティおよびリレーションシップにより
 アプリケーションで使用されるデータ構造 (格納
 形式ではなく) が記述されるため、アプリケー
 ションの進化に伴ってこれらを進化させること
 が可能



              VSUG DAY 2010.05.09
概念モデル、論理モデル、マッピング

概念スキーマ 定義言語(CSDL)
 EDMの概念を実装するDSL(Domain Specific
  Language)の1種
ストア スキーマ 定義言語(SSDL)
マッピング 仕様言語ファイル (MSL)




            VSUG DAY 2010.05.09
Entity Data Model の概念

 エンティティ型
   Entity Data Model でデータ構造を記述するために不可欠な構成要素
   継承をサポート
 アソシエーション型
   Entity Data Model でリレーションシップを記述するために不可欠な構
    成要素
   アソシエーションに含まれるエンティティ型を指定する 2 つのアソシ
    エーション End がある
   アソシエーションのその End に存在できるエンティティ数を示すアソ
    シエーション End の多重度も指定する必要がある
 プロパティ
   エンティティ型には、その構造と特性を定義するプロパティが含まれる
   プロパティには、プリミティブ データ (文字列、整数、ブール値など) または構
    造化データ (複合型) を含めることができる




                 VSUG DAY 2010.05.09
Entity Data Model でサポートされるプリミティブ データ型



プリミティブ           説明                       私用できるファセット
データ型
Binary           バイナリ データを格納              MaxLength、FixedLength、Nullable、Default
Boolean          true または false           Nullable、Default
Byte             符号なし 8 ビット整数             Precision、Nullable、Default
                 値
DateTime         日時                       Precision、Nullable、Default
DateTimeOffset   GMT からのオフセット Precision、Nullable、Default
                 (分単位) としての日時
Decimal          有効桁数と小数点以下               Precision、Nullable、Default
                 桁数が固定長の数値
Double           15 桁の有効桁数を持つ             Precision、Nullable、Default
                 浮動小数点数
Float            7 桁の有効桁数を持つ              Precision、Nullable、Default
                 浮動小数点数



                                  VSUG DAY 2010.05.09
Entity Data Model でサポートされるプリミティブ データ型



プリミティブ   説明               私用できるファセット
データ型
Guid     16 バイトの一意識別子     Precision、Nullable、Default
Int16    符号付き 16 ビット整     Precision、Nullable、Default
         数値
Int32    符号付き 32 ビット整     Precision、Nullable、Default
         数値
Int64    符号付き 64 ビット整     Precision、Nullable、Default
         数値
SByte    符号付き 8 ビット整数     Precision、Nullable、Default
         値
String   文字データ            Unicode、FixedLength、MaxLength、
                          Collation、Precision、Nullable、Default
Time     時刻を格納            Precision、Nullable、Default




                  VSUG DAY 2010.05.09
アソシエーション End

 アソシエーションに2つのアソシエーション
 End
 アソシエーション Endの定義に含まれる情報
  アソシエーションに含まれるエンティティ型
  多重度(1, 0..1, *)
  Endの名前
  CASCADE ON DELETEなどの操作




          VSUG DAY 2010.05.09
ADO.NET Entity Data Modelの作成




             VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
Object Servicesの概要

 Entity Framework ツールは、概念スキーマ定義言語
 (CSDL) ファイルを使用して、オブジェクト レイヤー
 コードを生成
   生成されるコードに含まれるデータクラス
     型指定された ObjectContext クラス
     エンティティ型を表し、EntityObject から継承したクラス
     複合型を表し、ComplexObject から継承したクラス
 オブジェクト コンテキスト
   以下のものをカプセル化
     データベースへの接続
     モデルを記述するメタデータ
     作成、更新、および削除の操作時にオブジェクトを追跡する
      ObjectStateManager オブジェクト



                VSUG DAY 2010.05.09
オブジェクト クエリ

 エンティティ セットを返す
    ObjectQuery (.NET Framework 3.5 SP1)
    ObjectSet (.NET Framework 4)
        ObjectQueryクラスを拡張、型指定されたエンティティ セッ
         トのコンテキストでオブジェクトの追加や削除の機能を追加
using (ChinookEntities context = new ChinookEntities())
{
    ObjectSet<Album> albums = context.Albums;
     var query = from album in albums
          where album.Artist.Name == "Deep Purple"
          select new { Title = album.Title, Name = album.Artist.Name };
    Console.WriteLine("Album title: ");
    foreach (var q in query)
    {
       Console.WriteLine(q.Name + ": " + q.Title);
    }
…
                             VSUG DAY 2010.05.09
クエリを返す方法

LINQ to Entities
  概念モデルで定義されているエンティティ型に対し
   てクエリを実行するための統合言語クエリ (LINQ) を
   サポート
Entity SQL
  SQL.ストレージに依存しない SQL 言語。概念モデル
   のエンティティを直接操作し、Entity Data Model の
   概念をサポート
クエリービルダーメソッド
  LINQ スタイルのクエリ メソッドを使用して Entity
   SQL クエリを構成


                   VSUG DAY 2010.05.09
Entity SQL

  Entity Framework 内の概念モデルに対するクエリの実行
  に使用できる SQL に似た言語
  概念モデルは、データをエンティティおよびリレーショ
  ンシップとして表す
  Entity SQL を使用すると、SQL を使用したことのある
  ユーザーが慣れている形式でそれらのエンティティおよ
  びリレーションシップに対してクエリを実行できる

SELECT VALUE p.Name FROM AdventureWorksEntities.Product as p




                          VSUG DAY 2010.05.09
クエリービルダーメソッド

ObjectQuery には、Entity SQL と等価のクエリ
コマンドを順番に構築するために使用できる一
連のクエリ ビルダー メソッドも実装されている
Distinct(), Except(), GroupBy(), Intersect(),
OfType(), OrderBy(), Select(), SelectValue(), Skip(),
Top(), Union(), UnionAll(), Where() など




                   VSUG DAY 2010.05.09
クエリの実行 LINQ to Entities




            VSUG DAY 2010.05.09
LINQ to Entities

    メソッドベースの構文例(射影)
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
  var query = AWEntities.Products
     .Select(product => new
     {
         ProductId = product.ProductID,
         ProductName = product.Name
     });

    Console.WriteLine("Product Info:");
    foreach (var productInfo in query)
    {
       Console.WriteLine("Product Id: {0} Product name: {1} ",
         productInfo.ProductId, productInfo.ProductName);
    }
}

                                 VSUG DAY 2010.05.09
LINQ to Entities

    クエリ式の構文例(射影)
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
  ObjectSet<Product> products = AWEntities.Products;
  IQueryable<Product> productsQuery = from product in products
                      select product;

    Console.WriteLine("Product Names:");
    foreach (var prod in productsQuery)
    {
       Console.WriteLine(prod.Name);
    }
}




                               VSUG DAY 2010.05.09
LINQ to Entities

  クエリ式の構文例(フィルター処理)
ObjectSet<SalesOrderHeader> orders = AWEntities.SalesOrderHeaders;

 var onlineOrders =
   from order in orders
   where order.OnlineOrderFlag == true
   select new
   {
      SalesOrderID = order.SalesOrderID,
      OrderDate = order.OrderDate,
      SalesOrderNumber = order.SalesOrderNumber
   };




                           VSUG DAY 2010.05.09
LINQ to Entities

  クエリ式の構文例(集計演算子処理)
ObjectSet<Product> products = AWEntities.Products;

 var query = from product in products
        group product by product.Style into g
        select new
        {
           Style = g.Key,
           AverageListPrice =
              g.Average(product => product.ListPrice)
        };

 foreach (var product in query)
 {
    Console.WriteLine("Product style: {0} Average list price: {1}",
      product.Style, product.AverageListPrice);
 }

                               VSUG DAY 2010.05.09
LINQ to Entities

  クエリ式の構文例(パーティション分割)
var query = (from album in albums
                 where album.Artist.Name == "Deep Purple"
                 orderby album.Title
                 select new
                {
                    Title = album.Title,
                    Name = album.Artist.Name
                }).Take(3);




                           VSUG DAY 2010.05.09
LINQ to Entities

  クエリ式の構文例(結合演算子)
   GroupJoin() 左外部結合に相当
 var query =
    from contact in contacts
    join order in orders
    on contact.ContactID
    equals order.Contact.ContactID into contactGroup
    select new
    {
       ContactID = contact.ContactID,
       OrderCount = contactGroup.Count(),
       Orders = contactGroup.Select(order => order)
    };




                            VSUG DAY 2010.05.09
LINQ to Entities

  クエリ式の構文例(グループ化)
 var query = (
   from contact in contacts
   group contact by contact.LastName.Substring(0, 1) into contactGroup
   select new { FirstLetter = contactGroup.Key,
               ContactGroup = contactGroup }).
      OrderBy(letter => letter.FirstLetter);

 foreach (var contact in query)
 {
    Console.WriteLine("Last names that start with the letter '{0}':",
       contact.FirstLetter);
    foreach (var name in contact.ContactGroup)
    {
       Console.WriteLine(name.LastName);
    }
 }

                               VSUG DAY 2010.05.09
関連オブジェクトの読み込み

読み込みパターン   説明

クエリで指定する   ナビゲーション プロパティを使用

明示的読み込み    Loadメソッドを使用

遅延読み込み     LazyLoadingEnabledプロパティをtrueにセット

一括読み込み     ObjectQuery で Include(String) メソッドを使用




                VSUG DAY 2010.05.09
関連するオブジェクトを明示的に読み込む


Contact customer = context.Contacts
      .Where("it.ContactID = @customerId",
      new ObjectParameter("customerId", customerId)).First();

    if (!customer.SalesOrderHeaders.IsLoaded)
    {
        customer.SalesOrderHeaders.Load();
    }

    foreach (SalesOrderHeader order in customer.SalesOrderHeaders)
    {
       if (!order.SalesOrderDetails.IsLoaded)
       {
           order.SalesOrderDetails.Load();
       }




                             VSUG DAY 2010.05.09
遅延読み込み

Entity Framework ツールを使用して新しいモデルおよび
対応する生成済みクラスを作成する場合、
LazyLoadingEnabled の既定値は true
 context.ContextOptions.LazyLoadingEnabled = true;

遅延読み込みは、単一オブジェクト (EntityReference な
ど) とオブジェクトのコレクション (EntityCollection な
ど) の両方を返すナビゲーション プロパティでサポート
遅延読み込みが有効であっても、関連オブジェクトが既
に読み込まれているなら、関連オブジェクトが再度読み
込まれることはない
遅延読み込みは、Detached() 状態にあるオブジェクトで
サポートされる。この場合、関連オブジェクトも
Detached() 状態で返される
                         VSUG DAY 2010.05.09
一括読み込み(クエリ パスの定義)

var contacts = (from contact in context.Contacts
            .Include("SalesOrderHeaders.SalesOrderDetails")
              select contact).FirstOrDefault();
  try
  {
     foreach (SalesOrderHeader order in contacts.SalesOrderHeaders)
     {
        Console.WriteLine(String.Format("PO Number: {0}",
           order.PurchaseOrderNumber));
        Console.WriteLine(String.Format("Order Date: {0}",
           order.OrderDate.ToString()));
        Console.WriteLine("Order items:");
        foreach (SalesOrderDetail item in order.SalesOrderDetails)
        {
           Console.WriteLine(String.Format("Product: {0} "
              + "Quantity: {1}", item.ProductID.ToString(),
              item.OrderQty.ToString()));
        }
     }
                             VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
オブジェクトの作成と追加

using (ChinookEntities context = new ChinookEntities())
{
ObjectSet<Artist> artists = context.Artists;

//ArtistIdはIdentityとして宣言されているので、初期値(0)は無視される
Artist artist = Artist.CreateArtist(0);

artist.Name = "Atsushi Fukui";
artists.AddObject(artist);
context.SaveChanges();

Console.WriteLine("Added Artist id {0} name {1}", artist.ArtistId, artist.Name);




                                 VSUG DAY 2010.05.09
オブジェクトの削除

using (ChinookEntities context = new ChinookEntities())
{
  ObjectSet<Artist> artists = context.Artists;
  Artist artist = artists.Where("it.Name=@name",
                new ObjectParameter("name", "Atsushi Fukui")).First();
  if (artist != null)
  {
      artists.DeleteObject(artist);
      context.SaveChanges();
  }
}




                                VSUG DAY 2010.05.09
オブジェクトの更新

object entity = null;
IEnumerable<KeyValuePair<string, object>> keyValues =
                     new KeyValuePair<string, object>[]{
                     new KeyValuePair<string, object>("ArtistId", 279)
                     };
EntityKey key = new EntityKey("ChinookEntities.Artists", keyValues);
if (context.TryGetObjectByKey(key, out entity))
{
    Artist artist = (Artist)entity;
    artist.Name = "Hideharu Moriya";
    context.SaveChanges();
}
Artist a = context.Artists.Where(o => o.ArtistId == 279).First();
if (a != null)
{
    Console.WriteLine(“artist id {0}, name {1}”, a.ArtistId, a.Name);
}


                               VSUG DAY 2010.05.09
ID管理、状態管理、変更の追跡

 ObjectStateEntry
  アタッチされている各オブジェクトに対して作成さ
   れる
  EntityKey と EntityState、関連するオブジェクトに関
   する情報、およびオブジェクトのプロパティの元の
   値と現在の値を格納
  エンティティがデタッチされると、対応する
   ObjectStateEntry オブジェクトがオブジェクト コンテ
   キストから削除される
  ObjectStateManager によって管理される
     各オブジェクト コンテキストについて、
      ObjectStateManager のインスタンスが 1 つ存在


                    VSUG DAY 2010.05.09
エンティティ状態

マージ        説明
オプション
Added      新しいオブジェクトがオブジェクト コンテキストに追加されている。
           SaveChanges() メソッドは呼び出されていない。変更が保存されると、
           オブジェクトの状態は Unchangedに変更される。
Deleted    オブジェクトがオブジェクト コンテキストから削除されている。変更
           が保存されると、オブジェクトの状態は Detachedに変更される。
Detached   オブジェクトが存在するが追跡されていない。エンティティは、作成さ
           れた直後とオブジェクト コンテキストに追加される直前にこの状態に
           なる。また、Detach(Object) メソッドを呼び出してコンテキストから削
           除された後、または NoTracking MergeOption を使用して読み込まれる
           場合にもこの状態になる。
Modified   オブジェクトのスカラー プロパティのいずれかが変更されている。
           SaveChangesメソッドは呼び出されていない。変更追跡プロキシを持た
           ない POCO エンティティでは、DetectChangesメソッドが呼び出された
           ときに、変更されているプロパティの状態が Modified に変わる。変更
           が保存されると、オブジェクトの状態は Unchangedに変わる。
Unchanged オブジェクトは、コンテキストに読み込まれた後、または最後に
          SaveChanges メソッドが呼び出されてから変更されていない。

                      VSUG DAY 2010.05.09
変更の追跡

Entity Framework により生成されたエンティティおよび変更追跡プ
ロキシ オブジェクトを持つ POCO エンティティに対しては、
ObjectStateEntry はオブジェクト プロパティの現在の値および変更
されたプロパティの元の値を格納する
Added 状態または Detached 状態にあるオブジェクトは、元の値を
保持していない
オブジェクト コンテキストは、プロパティが変更されると通知を受
け取り、ObjectStateEntry 内のオブジェクトの状態とプロパティの
値を更新する
ObjectStateEntry は、変更追跡プロキシの無いPOCOエンティティ、
および複合型オブジェクトでは異なる方法で管理する。これらの型
のオブジェクトに対し、ObjectStateEntryは、オブジェクトが最初
にコンテキストに入った時にオブジェクト プロパティの値のスナッ
プショットを取得し、元の値のセットと現在の値のセットを格納す
る。


              VSUG DAY 2010.05.09
ID解決とマージ

   特定のエンティティ キーを持つオブジェクトの
   1 つのみのインスタンスをキャッシュ内に保持
   する
   同じ ID を持つエンティティが既に追跡されてい
   る場合、データ ソースからのデータと状態マ
   ネージャーに既に存在するデータは、クエリの
   MergeOption に従ってマージされる

var orders = Customer.Orders.Execute(MergeOption.PreserveChanges);




                            VSUG DAY 2010.05.09
マージ オプション

マージ オプション          説明

AppendOnly         オブジェクト コンテキストに存在しないオブジェクトは、コンテキストに
                   アタッチされる。オブジェクト コンテキストに存在するオブジェクトのプ
                   ロパティは、データ ソースの値によって上書きされない。AppendOnly()
                   は既定のマージ オプション
OverwriteChanges   オブジェクト コンテキストに存在しないオブジェクトは、コンテキストに
                   アタッチされる。オブジェクト コンテキストに存在するオブジェクトのプ
                   ロパティは、データ ソースの値によって上書きされる。
PreserveChanges    .NET Framework バージョン 3.5 SP1 では、オブジェクト コンテキスト内
                   のオブジェクトのプロパティ値がサーバー上の値と異なる場合、オブジェ
                   クト コンテキスト内のプロパティ値は、オブジェクトが Unchanged状態
                   にない限り、保持される。Unchanged状態の場合は、プロパティがデータ
                   ソースの値で上書きされる。
                   .NET Framework バージョン 4 では、オブジェクト コンテキスト内のオブ
                   ジェクトの値はすべて、オブジェクトの状態にかかわらず保持される。

NoTracking         オブジェクトは、Detached状態で保持され、ObjectStateManager では追
                   跡されない。ただし、Entity Framework により生成されたエンティティお
                   よびプロキシを持つ POCO エンティティは、関連するオブジェクトの読み
                   込みを容易にするために、オブジェクト コンテキストへの参照を保持する。



                           VSUG DAY 2010.05.09
同時実行制御チェック

ConcurrencyMode=“Fixed” を使用すると
Entity Framework は、変更をデータベース
に保存する前に、データベース内の変更
をチェックする
SQL Serverの場合、各テーブルにタイムス
タンプ列を追加して指定すると良い
 他のデータベースの場合はトリガでタイムス
  タンプを更新するなど



          VSUG DAY 2010.05.09
同時実行制御チェック




       VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
Entity Data Model: 継承

  概念モデルでは派生型は基本型のすべてのプロ
  パティとナビゲーション プロパティを継承
  ルート型はエンティティ キーを定義する必要が
  ある
  単一継承のみ可能
  CSDLによる定義例
 <EntityType Name="FictionBook" BaseType="BooksModel.Book" >
           <Property Type="String" Name="Genre" Nullable="false" />
 </EntityType>




                           VSUG DAY 2010.05.09
概念モデルの継承の実装方式

Table-Per-Type継承
  概念スキーマで派生型のBaseType属性に基本エンティティ型を
   指定
  基本エンティティを抽象型として定義
  派生型のIDを削除
  マッピングの詳細ウィンドウでIDを基本エンティティのIDに
   マップ
Table-Per-Hierarchy 継承
  概念スキーマで派生型のBaseType属性に基本エンティティ型を
   指定
  マッピングの詳細ウィンドウで「テーブルまたはビューの追
   加」からテーブルを選択
  条件の追加でプロパティにIs NullまたはIs Not Nullを設定


                   VSUG DAY 2010.05.09
自動生成されるSQLの一部

-- Creating table 'Parties'
CREATE TABLE [dbo].[Parties] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [Name] nvarchar(max) NOT NULL
);
GO

-- Creating table 'Parties_Organization'
CREATE TABLE [dbo].[Parties_Organization] (
    [Location] nvarchar(max) NOT NULL,
    [Id] int NOT NULL
);
GO

-- Creating table 'Parties_Person'
CREATE TABLE [dbo].[Parties_Person] (
    [Age] int NOT NULL,
    [Id] int NOT NULL
);
GO

                            VSUG DAY 2010.05.09
エンティティの継承




       VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
N層アプリケーションとは

クライアント層、中間サービス層、デー
タベース層に分かれる
 ASP.NETアプリケーション
 WCFサービス、Webサービスを利用するアプ
  リケーション
 Silverlightアプリケーション
オブジェクトをシリアル化して他の層に
転送し逆シリアル化して利用
更新された情報を何らかの方法で保持す
る必要がある
         VSUG DAY 2010.05.09
オブジェクトのシリアル化

オブジェクトをシリアル化すると、EntityKey オブジェクトもシリ
アル化される
バイナリ シリアル化と WCF データ コントラクト シリアル化を使
用する場合に、シリアル化するオブジェクトのオブジェクト グラフ
に関連オブジェクトがあると、これらのオブジェクトもシリアル化
される
XML シリアル化では、関連オブジェクトはシリアル化されない
オブジェクトのプロパティとリレーションシップ情報だけがシリア
ル化される
オブジェクト コンテキストで維持されているオブジェクトの状態情
報はシリアル化されない
.NET Framework バージョン 4 から、自己追跡エンティティで独自
の変更追跡ロジックを利用できるようになった(後述)
オブジェクトが逆シリアル化された後、オブジェクトは Detached()
状態になる

             VSUG DAY 2010.05.09
オブジェクトのアタッチ、デタッチ

Entity Framework では、オブジェクト コンテキスト内で
クエリを実行すると、返されたオブジェクトがそのオブ
ジェクト コンテキストに自動的にアタッチされる
以前にデタッチされているオブジェクト、NoTracking()
クエリによって返されたオブジェクト、またはオブジェ
クト コンテキストの外部で取得したオブジェクトなど
もアタッチできる
ASP.NET アプリケーションのビュー ステートに保存さ
れていたオブジェクトや、リモート メソッド呼び出し
または Web サービスによって返されたオブジェクトも
アタッチできる



            VSUG DAY 2010.05.09
変更の適用(デタッチ オブジェクト)

 単純にアタッチされた場合、そのオブジェクト
 が既にオブジェクト コンテキスト内にあると、
 更新が失われるか、操作が失敗する
 (Unchanged状態でアタッチされるため)
 オリジナルのオブジェクトと変更後のオブジェ
 クトをクライアントから返してもらうことでオ
 ブジェクト コンテキストにアタッチしたオブ
 ジェクトに変更を適用する




         VSUG DAY 2010.05.09
オブジェクトをアタッチするメソッド

メンバー                         説明
ObjectSetAddObject()         オブジェクトとその関連オブジェクトを ObjectContext
または                          に追加し、エンティティ オブジェクトを Added 状態に
ObjectContextAddObject(S     設定します。この状態では、エンティティ オブジェクト
tring, Object)               の一意のキー値を持つ必要はない。一時的なキー値が
                             キーのプロパティに割り当てられ、オブジェクトの保存
                             後にデータ ソースが生成した値で更新される。オブジェ
                             クトを追加後、エンティティ オブジェクトの状態が適切
                             に変更される。
ObjectSetAttach()            オブジェクトを ObjectContext に追加し、オブジェクト
または                          を Unchanged 状態に設定する。Unchanged 状態では、
ObjectContextAttach(IEntit   Entity Framework はエンティティ キーの値を最終版とし
yWithKey)                    て処理する。特定の型の複数のエンティティに同じキー
と                            の値がある場合は、Entity Framework は例外をスローす
AttachTo(String, Object)     る。例外を回避するには、AddObject メソッドを使用し
                             てデタッチされたオブジェクトをアタッチし、適切な状
                             態に変更する。




                               VSUG DAY 2010.05.09
アタッチして変更を適用する例

private static void ApplyItemUpdates(
     SalesOrderDetail originalItem, SalesOrderDetail updatedItem)
{
   using (AdventureWorksEntities advWorksContext = new AdventureWorksEntities())
   {
     try
     {
        //オリジナルのItemをオブジェクト コンテキストにアタッチ
        advWorksContext.Attach(originalItem);

          //変更を適用するためにApplyCurrentValuesメソッドを使用
          advWorksContext.ApplyCurrentValues(“SalesOrderDetails”, updatedItem);
          advWorksContext.SaveChanges();
        }
        catch (InvalidOperationException ex)
        {
          Console.WriteLine(ex.ToString());
        }
    }
}


                                     VSUG DAY 2010.05.09
自己追跡エンティティ




       VSUG DAY 2010.05.09
自己追跡エンティティ

//クライアント側コード

static void UpdateDepartmentAndCourses(int departmentID, int courseID)
      {
        using (var service = new Service1Client())
        {
           List<Department> departments = service.GetDepartments();
           Department department = departments.Single(
                                 d => d.DepartmentID == departmentID);
           department.Budget = department.Budget - 1000.00m;

            Course existingCourse = department.Courses.Single(
                                           c => c.CourseID == courseID);
            existingCourse.Credits = 3;

            service.UpdateDepartment(department);
        }
    }




                                   VSUG DAY 2010.05.09
自己追跡エンティティ

//サービス側コード

public void UpdateDepartment(Department updated)
{
   using (SchoolEntities context = new SchoolEntities())
  {
     try
     {
         context.Departments.ApplyChanges(updated);
         context.SaveChanges();
      }
      catch (UpdateException)
      {
         throw;
       }
  }
}


                              VSUG DAY 2010.05.09
まとめ

ADO.NET Entity FrameworkはEDMの実装を提供
概念スキーマ定義とストア スキーマ定義をマッピング
することでストアに非依存なモデルを利用可能
  エンティティとアソシエーションの概念
同時実行制御チェックを有効にする
オブジェクト状態を理解する
N層アプリケーションと自己追跡エンティティ
  WCF サービス アプリケーションとの連携
  ObjectContextをサービス層でキャッシュするのはアンチパタン
継承エンティティによるテーブル マッピング
その他
  IObjectSetの利用によってテスト容易性が向上している

              VSUG DAY 2010.05.09
参考資料

Entity Framework を使用した n 層アプリケーションで回
避すべきアンチパターン
http://msdn.microsoft.com/ja-jp/magazine/dd882522.aspx
n 層アプリケーションのパターン
http://msdn.microsoft.com/ja-jp/magazine/ee321569.aspx
チュートリアル: ストアド プロシージャへのエンティ
ティのマッピング
http://msdn.microsoft.com/ja-jp/library/cc716679(v=VS.100).aspx
Walkthrough: Serialize Self-Tracking Entities (Entity
Framework) (英語)
http://msdn.microsoft.com/en-us/library/ee789839(v=VS.100).aspx
Entity Framework FAQ(英語)
http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx


                       VSUG DAY 2010.05.09
VSUG DAY 2010.05.09
Appendix




           VSUG DAY 2010.05.09
EdmGen.exe

   コマンドラインによるオブジェクト レイ
   ヤ生成
C#のコード生成

"%windir%¥Microsoft.NET¥Framework¥v4.0.30319¥edmgen.exe"
/mode:EntityClassGeneration
/incsdl:.¥School.csdl /outobjectlayer:.¥School.Objects.cs /language:CSharp


VBのコード生成

"%windir%¥Microsoft.NET¥Framework¥v4.0.30319¥edmgen.exe"
/mode:EntityClassGeneration
/incsdl:.¥School.csdl /outobjectlayer:.¥School.Objects.vb /language:VB



                              VSUG DAY 2010.05.09
概念スキーマ 定義言語: EntityContainer

…
<EntityContainer Name="ChinookEntities“
       annotation:LazyLoadingEnabled="true">
   <EntitySet Name="Albums"
   EntityType="ChinookModel.Album" />
   <EntitySet Name="Artists"
   EntityType="ChinookModel.Artist" />
   <AssociationSet Name="FK__Album__ArtistId__108B795B“

   Association="ChinookModel.FK__Album__ArtistId__108B795B"
   >
     <End Role="Artist" EntitySet="Artists" />
     <End Role="Album" EntitySet="Albums" />
     </AssociationSet>
 </EntityContainer>
 …

                      VSUG DAY 2010.05.09
概念スキーマ 定義言語: EntityType

…
<EntityType Name="Album">
  <Key>
    <PropertyRef Name="AlbumId" />
  </Key>
  <Property Name="AlbumId" Type="Int32" Nullable="false"
       annotation:StoreGeneratedPattern="Identity" />
  <Property Name="Title" Type="String" Nullable="false"
   MaxLength="160" Unicode="true" FixedLength="false" />
<Property Name="ArtistId" Type="Int32" Nullable="false" />
<NavigationProperty Name="Artist“
Relationship="ChinookModel.FK__Album__ArtistId__108B795B“
  FromRole="Album" ToRole="Artist" />
</EntityType>
…


                      VSUG DAY 2010.05.09
概念スキーマ 定義言語: Association

…
<Association Name="FK__Album__ArtistId__108B795B">
  <End Type="ChinookModel.Artist" Role="Artist"
       Multiplicity="1" />
  <End Type="ChinookModel.Album" Role="Album"
   Multiplicity="*" />
   <ReferentialConstraint>
      <Principal Role="Artist">
        <PropertyRef Name="ArtistId" />
      </Principal>
     <Dependent Role="Album">
        <PropertyRef Name="ArtistId" />
      </Dependent>
     </ReferentialConstraint>
  </Association>
…

                      VSUG DAY 2010.05.09
ストア スキーマ 定義言語: EntityContainer

…
 <EntityContainer Name="ChinookModelStoreContainer">
   <EntitySet Name="Album“
     EntityType="ChinookModel.Store.Album"
     store:Type="Tables" Schema="dbo" />
   <EntitySet Name="Artist"
     EntityType="ChinookModel.Store.Artist"
     store:Type="Tables" Schema="dbo" />
 <AssociationSet Name="FK__Album__ArtistId__108B795B"
Association="ChinookModel.Store.FK__Album__ArtistId__108B7
95B">
  <End Role="Artist" EntitySet="Artist" />
  <End Role="Album" EntitySet="Album" />
  </AssociationSet>
</EntityContainer>
…
                      VSUG DAY 2010.05.09
ストア スキーマ 定義言語: EntityType

…
<EntityType Name="Album">
  <Key><PropertyRef Name="AlbumId" /></Key>
  <Property Name="AlbumId" Type="int" Nullable="false"
  StoreGeneratedPattern="Identity" />
  <Property Name="Title" Type="nvarchar"
   Nullable="false" MaxLength="160" />
  <Property Name="ArtistId" Type="int" Nullable="false" />
</EntityType>
<EntityType Name="Artist">
  <Key><PropertyRef Name="ArtistId" /></Key>
  <Property Name="ArtistId" Type="int" Nullable="false"
   StoreGeneratedPattern="Identity" />
  <Property Name="Name" Type="nvarchar" MaxLength="120" />
</EntityType>
…
                       VSUG DAY 2010.05.09
ストア スキーマ 定義言語: Association

…
 <Association Name="FK__Album__ArtistId__108B795B">
  <End Role="Artist" Type="ChinookModel.Store.Artist"
   Multiplicity="1" />
  <End Role="Album" Type="ChinookModel.Store.Album"
   Multiplicity="*" />
 <ReferentialConstraint>
   <Principal Role="Artist">
    <PropertyRef Name="ArtistId" />
   </Principal>
   <Dependent Role="Album">
    <PropertyRef Name="ArtistId" />
   </Dependent>
  </ReferentialConstraint>
</Association>
…
                      VSUG DAY 2010.05.09
マッピング 仕様言語: EntityMapping

…
<EntitySetMapping Name="Albums">
   <EntityTypeMapping
     TypeName="ChinookModel.Album">
    <MappingFragment
      StoreEntitySet="Album">
   <ScalarProperty Name="AlbumId" ColumnName="AlbumId" />
   <ScalarProperty Name="Title" ColumnName="Title" />
   <ScalarProperty Name="ArtistId" ColumnName="ArtistId" />
    </MappingFragment>
   </EntityTypeMapping>
  </EntitySetMapping>
…




                       VSUG DAY 2010.05.09
データベースへの接続

以下の場合に自動的に接続
  ObjectContext に対する SaveChanges()、または
   Refresh(RefreshMode, IEnumerable)
  ObjectQuery に対する FirstOrDefault(IEnumerable<UMP>)、ま
   たは First(IEnumerable<UMP>)
  EntityCollection に対する Load(MergeOption)
  EntityReference に対する Load(MergeOption)
  任意の統合言語クエリ (LINQ) メソッドまたは ObjectQuery クエ
   リ ビルダー メソッド (Where(String, ObjectParameter[])、
   OrderBy(String, ObjectParameter[])、Select(String,
   ObjectParameter[]) など)
  接続は、ObjectResult が完全に消費されるか破棄されるまで開
   いたままになる



                   VSUG DAY 2010.05.09
接続を手動で開く

using (AdventureWorksEntities advWorksContext = new AdventureWorksEntities())
{
  try {
     //明示的に接続を開く
     advWorksContext.Connection.Open();
     // オーダーを返すクエリを実行
     SalesOrderHeader order = advWorksContext.SalesOrderHeaders.Where(
        "it.SalesOrderID = @orderId", new ObjectParameter("orderId", orderId))
        .Execute(MergeOption.AppendOnly).First();

         order.Status = 1;
     // 変更を保存
     if (0 < advWorksContext.SaveChanges())
     {
         Console.WriteLine("Changes saved.");
     }
    }
    catch (InvalidOperationException ex) {
       Console.WriteLine(ex.ToString());
    }
    // オブジェクト コンテキストがDisposeされるときに接続は閉じられる
}
                                  VSUG DAY 2010.05.09

Mais conteúdo relacionado

Semelhante a VSUG Day 2010 Summer - Using ADO.NET Entity Framework

DDD 20121106 SEA Forum November
DDD 20121106 SEA Forum NovemberDDD 20121106 SEA Forum November
DDD 20121106 SEA Forum November増田 亨
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう増田 亨
 
Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編Microsoft Azure Japan
 
20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architecture20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architectureIssei Hiraoka
 
Apexコアデベロッパーセミナー070726 配布用
Apexコアデベロッパーセミナー070726 配布用Apexコアデベロッパーセミナー070726 配布用
Apexコアデベロッパーセミナー070726 配布用stomita
 
Windows ストア アプリの上手な作り方
Windows ストア アプリの上手な作り方Windows ストア アプリの上手な作り方
Windows ストア アプリの上手な作り方一希 大田
 
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現インフラジスティックス・ジャパン株式会社
 
ドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDDドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDD増田 亨
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Shotaro Suzuki
 
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Shotaro Suzuki
 
「エクストリームエンジニアへの道(Swift編)」
「エクストリームエンジニアへの道(Swift編)」「エクストリームエンジニアへの道(Swift編)」
「エクストリームエンジニアへの道(Swift編)」tech-arts
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へDevelopers Summit
 
そのデータ、活かせていますか?
そのデータ、活かせていますか?そのデータ、活かせていますか?
そのデータ、活かせていますか?Miho Yamamoto
 
CEDEC 2013 Unity on Windows 8
CEDEC 2013 Unity on Windows 8CEDEC 2013 Unity on Windows 8
CEDEC 2013 Unity on Windows 8Akira Onishi
 
勉強会force#3 iOSアプリ開発
勉強会force#3 iOSアプリ開発勉強会force#3 iOSアプリ開発
勉強会force#3 iOSアプリ開発Kazuki Nakajima
 
ADO.NET Entity Framework
ADO.NET Entity Framework ADO.NET Entity Framework
ADO.NET Entity Framework Microsoft
 

Semelhante a VSUG Day 2010 Summer - Using ADO.NET Entity Framework (20)

DDD 20121106 SEA Forum November
DDD 20121106 SEA Forum NovemberDDD 20121106 SEA Forum November
DDD 20121106 SEA Forum November
 
20110607
2011060720110607
20110607
 
Mvc conf session_4_ono
Mvc conf session_4_onoMvc conf session_4_ono
Mvc conf session_4_ono
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編
 
20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architecture20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architecture
 
Apexコアデベロッパーセミナー070726 配布用
Apexコアデベロッパーセミナー070726 配布用Apexコアデベロッパーセミナー070726 配布用
Apexコアデベロッパーセミナー070726 配布用
 
Windows ストア アプリの上手な作り方
Windows ストア アプリの上手な作り方Windows ストア アプリの上手な作り方
Windows ストア アプリの上手な作り方
 
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現
Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現
 
ドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDDドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDD
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
 
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
 
APIKit
APIKitAPIKit
APIKit
 
「エクストリームエンジニアへの道(Swift編)」
「エクストリームエンジニアへの道(Swift編)」「エクストリームエンジニアへの道(Swift編)」
「エクストリームエンジニアへの道(Swift編)」
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
 
そのデータ、活かせていますか?
そのデータ、活かせていますか?そのデータ、活かせていますか?
そのデータ、活かせていますか?
 
CEDEC 2013 Unity on Windows 8
CEDEC 2013 Unity on Windows 8CEDEC 2013 Unity on Windows 8
CEDEC 2013 Unity on Windows 8
 
勉強会force#3 iOSアプリ開発
勉強会force#3 iOSアプリ開発勉強会force#3 iOSアプリ開発
勉強会force#3 iOSアプリ開発
 
[Japan Tech summit 2017] DAL 006
[Japan Tech summit 2017] DAL 006[Japan Tech summit 2017] DAL 006
[Japan Tech summit 2017] DAL 006
 
ADO.NET Entity Framework
ADO.NET Entity Framework ADO.NET Entity Framework
ADO.NET Entity Framework
 

Mais de Atsushi Fukui

「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発Atsushi Fukui
 
[AWS Developers Meetup 2017] Developerのための ライブAWSウォークスルー 〜 AWS SDKの使い方 〜
[AWS Developers Meetup 2017] DeveloperのためのライブAWSウォークスルー 〜 AWS SDKの使い方 〜[AWS Developers Meetup 2017] DeveloperのためのライブAWSウォークスルー 〜 AWS SDKの使い方 〜
[AWS Developers Meetup 2017] Developerのための ライブAWSウォークスルー 〜 AWS SDKの使い方 〜Atsushi Fukui
 
20170809 AWS code series
20170809 AWS code series20170809 AWS code series
20170809 AWS code seriesAtsushi Fukui
 
Introducing C# in AWS Lambda
Introducing C# in AWS LambdaIntroducing C# in AWS Lambda
Introducing C# in AWS LambdaAtsushi Fukui
 
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたか
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたかVSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたか
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたかAtsushi Fukui
 
Introduction to application architecture on asp.net mvc
Introduction to application architecture on asp.net mvcIntroduction to application architecture on asp.net mvc
Introduction to application architecture on asp.net mvcAtsushi Fukui
 
Architecture driven development のすすめ
Architecture driven development のすすめArchitecture driven development のすすめ
Architecture driven development のすすめAtsushi Fukui
 
13_B_5 Who is a architect?
13_B_5 Who is a architect?13_B_5 Who is a architect?
13_B_5 Who is a architect?Atsushi Fukui
 
Vsug Leaders Summit 2008:A.Fukui
Vsug Leaders Summit 2008:A.FukuiVsug Leaders Summit 2008:A.Fukui
Vsug Leaders Summit 2008:A.FukuiAtsushi Fukui
 

Mais de Atsushi Fukui (10)

「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
 
[AWS Developers Meetup 2017] Developerのための ライブAWSウォークスルー 〜 AWS SDKの使い方 〜
[AWS Developers Meetup 2017] DeveloperのためのライブAWSウォークスルー 〜 AWS SDKの使い方 〜[AWS Developers Meetup 2017] DeveloperのためのライブAWSウォークスルー 〜 AWS SDKの使い方 〜
[AWS Developers Meetup 2017] Developerのための ライブAWSウォークスルー 〜 AWS SDKの使い方 〜
 
20170809 AWS code series
20170809 AWS code series20170809 AWS code series
20170809 AWS code series
 
Introducing C# in AWS Lambda
Introducing C# in AWS LambdaIntroducing C# in AWS Lambda
Introducing C# in AWS Lambda
 
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたか
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたかVSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたか
VSUGアーキテクトパネル アーキテクトはテクノロジーの進化にどのように対応してきたか
 
Introduction to application architecture on asp.net mvc
Introduction to application architecture on asp.net mvcIntroduction to application architecture on asp.net mvc
Introduction to application architecture on asp.net mvc
 
Architecture driven development のすすめ
Architecture driven development のすすめArchitecture driven development のすすめ
Architecture driven development のすすめ
 
鉄人28号と私
鉄人28号と私鉄人28号と私
鉄人28号と私
 
13_B_5 Who is a architect?
13_B_5 Who is a architect?13_B_5 Who is a architect?
13_B_5 Who is a architect?
 
Vsug Leaders Summit 2008:A.Fukui
Vsug Leaders Summit 2008:A.FukuiVsug Leaders Summit 2008:A.Fukui
Vsug Leaders Summit 2008:A.Fukui
 

Último

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 

Último (8)

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 

VSUG Day 2010 Summer - Using ADO.NET Entity Framework

  • 1. VSUG DAY 2010 Summer ADO.NET Entity Framework を使いこなそう 福井 厚 ( Twitter: @afukui ) VSUG運営委員 Microsoft Certified Architect Microsoft Regional Director Microsoft MVP for Visual C#
  • 2. 自己紹介 福井 厚 (ふくい あつし) アバナード株式会社 Group Manager / CTO Architect Visual Studio User Group 運営委員 Microsoft Certified Architect (MCA) Microsoft Regional Director Microsoft MVP for Visual Developer – C# Blog: http://www.users.gr.jp/blogs/fukui/ Twitter: @afukui VSUG DAY 2010.05.09
  • 4. Agenda ADO.NET Entity Frameworkとは EDM(Entity Domain Model)とは ObjectServicesとクエリ オブジェクトの追加、更新、削除 同時実行制御 エンティティ状態と変更の追跡 エンティティの継承と抽象化 N層アプリと自己追跡エンティティ まとめ VSUG DAY 2010.05.09
  • 5. 一般的な設計アプローチ ドメイン モデル、設計モデル、物理モデルの3つに分 割 ドメイン モデル  対象となるシステムに存在するエンティティとリ レーションシップを定義 設計モデル  外部キー制約を用いながら、エンティティとリレーションシッ プをテーブルとして正規化(RDBの場合) 物理モデル  パーティション分割やインデックス化などのストレージ情報を 指定することで、特定のデータ エンジンの機能に対応 VSUG DAY 2010.05.09
  • 6. 開発アプローチ ドメイン モデル駆動 概念モデルをストレートにマッピング 複雑なビジネス ロジック データベース駆動 データ中心アプローチ 既存のDBテーブルの活用 ユーザー インターフェース駆動 モックアップから開発 VSUG DAY 2010.05.09
  • 8. Entity Frameworkとは データ指向のソフトウェア アプリケー ション開発をサポートする ADO.NET のテ クノロジ セット データが格納されている、基になるデー タベース テーブルや列を意識することな く、顧客や顧客の住所など、ドメイン固 有のオブジェクトおよびプロパティの形 式でデータを扱うことが可能 EDM(後述)の実装を提供 VSUG DAY 2010.05.09
  • 9. Entity Framework Architecture Object Services Entity Domain Model ObjectContext ObjectQuery<T> Data Class CSDL EntityClient EntityConnection MSL EntityCommand EntityDataReader SSDL VSUG DAY 2010.05.09
  • 11. EDM(Entity Domain Model)とは 格納される形式に関係なく、データ構造を記述 する一連の概念 ストレージ スキーマに依存しないエンティティ とリレーションシップでデータ構造を記述 エンティティおよびリレーションシップにより アプリケーションで使用されるデータ構造 (格納 形式ではなく) が記述されるため、アプリケー ションの進化に伴ってこれらを進化させること が可能 VSUG DAY 2010.05.09
  • 12. 概念モデル、論理モデル、マッピング 概念スキーマ 定義言語(CSDL) EDMの概念を実装するDSL(Domain Specific Language)の1種 ストア スキーマ 定義言語(SSDL) マッピング 仕様言語ファイル (MSL) VSUG DAY 2010.05.09
  • 13. Entity Data Model の概念 エンティティ型  Entity Data Model でデータ構造を記述するために不可欠な構成要素  継承をサポート アソシエーション型  Entity Data Model でリレーションシップを記述するために不可欠な構 成要素  アソシエーションに含まれるエンティティ型を指定する 2 つのアソシ エーション End がある  アソシエーションのその End に存在できるエンティティ数を示すアソ シエーション End の多重度も指定する必要がある プロパティ  エンティティ型には、その構造と特性を定義するプロパティが含まれる  プロパティには、プリミティブ データ (文字列、整数、ブール値など) または構 造化データ (複合型) を含めることができる VSUG DAY 2010.05.09
  • 14. Entity Data Model でサポートされるプリミティブ データ型 プリミティブ 説明 私用できるファセット データ型 Binary バイナリ データを格納 MaxLength、FixedLength、Nullable、Default Boolean true または false Nullable、Default Byte 符号なし 8 ビット整数 Precision、Nullable、Default 値 DateTime 日時 Precision、Nullable、Default DateTimeOffset GMT からのオフセット Precision、Nullable、Default (分単位) としての日時 Decimal 有効桁数と小数点以下 Precision、Nullable、Default 桁数が固定長の数値 Double 15 桁の有効桁数を持つ Precision、Nullable、Default 浮動小数点数 Float 7 桁の有効桁数を持つ Precision、Nullable、Default 浮動小数点数 VSUG DAY 2010.05.09
  • 15. Entity Data Model でサポートされるプリミティブ データ型 プリミティブ 説明 私用できるファセット データ型 Guid 16 バイトの一意識別子 Precision、Nullable、Default Int16 符号付き 16 ビット整 Precision、Nullable、Default 数値 Int32 符号付き 32 ビット整 Precision、Nullable、Default 数値 Int64 符号付き 64 ビット整 Precision、Nullable、Default 数値 SByte 符号付き 8 ビット整数 Precision、Nullable、Default 値 String 文字データ Unicode、FixedLength、MaxLength、 Collation、Precision、Nullable、Default Time 時刻を格納 Precision、Nullable、Default VSUG DAY 2010.05.09
  • 16. アソシエーション End アソシエーションに2つのアソシエーション End アソシエーション Endの定義に含まれる情報  アソシエーションに含まれるエンティティ型  多重度(1, 0..1, *)  Endの名前  CASCADE ON DELETEなどの操作 VSUG DAY 2010.05.09
  • 17. ADO.NET Entity Data Modelの作成 VSUG DAY 2010.05.09
  • 19. Object Servicesの概要 Entity Framework ツールは、概念スキーマ定義言語 (CSDL) ファイルを使用して、オブジェクト レイヤー コードを生成  生成されるコードに含まれるデータクラス  型指定された ObjectContext クラス  エンティティ型を表し、EntityObject から継承したクラス  複合型を表し、ComplexObject から継承したクラス オブジェクト コンテキスト  以下のものをカプセル化  データベースへの接続  モデルを記述するメタデータ  作成、更新、および削除の操作時にオブジェクトを追跡する ObjectStateManager オブジェクト VSUG DAY 2010.05.09
  • 20. オブジェクト クエリ エンティティ セットを返す  ObjectQuery (.NET Framework 3.5 SP1)  ObjectSet (.NET Framework 4)  ObjectQueryクラスを拡張、型指定されたエンティティ セッ トのコンテキストでオブジェクトの追加や削除の機能を追加 using (ChinookEntities context = new ChinookEntities()) { ObjectSet<Album> albums = context.Albums; var query = from album in albums where album.Artist.Name == "Deep Purple" select new { Title = album.Title, Name = album.Artist.Name }; Console.WriteLine("Album title: "); foreach (var q in query) { Console.WriteLine(q.Name + ": " + q.Title); } … VSUG DAY 2010.05.09
  • 21. クエリを返す方法 LINQ to Entities  概念モデルで定義されているエンティティ型に対し てクエリを実行するための統合言語クエリ (LINQ) を サポート Entity SQL  SQL.ストレージに依存しない SQL 言語。概念モデル のエンティティを直接操作し、Entity Data Model の 概念をサポート クエリービルダーメソッド  LINQ スタイルのクエリ メソッドを使用して Entity SQL クエリを構成 VSUG DAY 2010.05.09
  • 22. Entity SQL Entity Framework 内の概念モデルに対するクエリの実行 に使用できる SQL に似た言語 概念モデルは、データをエンティティおよびリレーショ ンシップとして表す Entity SQL を使用すると、SQL を使用したことのある ユーザーが慣れている形式でそれらのエンティティおよ びリレーションシップに対してクエリを実行できる SELECT VALUE p.Name FROM AdventureWorksEntities.Product as p VSUG DAY 2010.05.09
  • 23. クエリービルダーメソッド ObjectQuery には、Entity SQL と等価のクエリ コマンドを順番に構築するために使用できる一 連のクエリ ビルダー メソッドも実装されている Distinct(), Except(), GroupBy(), Intersect(), OfType(), OrderBy(), Select(), SelectValue(), Skip(), Top(), Union(), UnionAll(), Where() など VSUG DAY 2010.05.09
  • 24. クエリの実行 LINQ to Entities VSUG DAY 2010.05.09
  • 25. LINQ to Entities メソッドベースの構文例(射影) using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()) { var query = AWEntities.Products .Select(product => new { ProductId = product.ProductID, ProductName = product.Name }); Console.WriteLine("Product Info:"); foreach (var productInfo in query) { Console.WriteLine("Product Id: {0} Product name: {1} ", productInfo.ProductId, productInfo.ProductName); } } VSUG DAY 2010.05.09
  • 26. LINQ to Entities クエリ式の構文例(射影) using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()) { ObjectSet<Product> products = AWEntities.Products; IQueryable<Product> productsQuery = from product in products select product; Console.WriteLine("Product Names:"); foreach (var prod in productsQuery) { Console.WriteLine(prod.Name); } } VSUG DAY 2010.05.09
  • 27. LINQ to Entities クエリ式の構文例(フィルター処理) ObjectSet<SalesOrderHeader> orders = AWEntities.SalesOrderHeaders; var onlineOrders = from order in orders where order.OnlineOrderFlag == true select new { SalesOrderID = order.SalesOrderID, OrderDate = order.OrderDate, SalesOrderNumber = order.SalesOrderNumber }; VSUG DAY 2010.05.09
  • 28. LINQ to Entities クエリ式の構文例(集計演算子処理) ObjectSet<Product> products = AWEntities.Products; var query = from product in products group product by product.Style into g select new { Style = g.Key, AverageListPrice = g.Average(product => product.ListPrice) }; foreach (var product in query) { Console.WriteLine("Product style: {0} Average list price: {1}", product.Style, product.AverageListPrice); } VSUG DAY 2010.05.09
  • 29. LINQ to Entities クエリ式の構文例(パーティション分割) var query = (from album in albums where album.Artist.Name == "Deep Purple" orderby album.Title select new { Title = album.Title, Name = album.Artist.Name }).Take(3); VSUG DAY 2010.05.09
  • 30. LINQ to Entities クエリ式の構文例(結合演算子) GroupJoin() 左外部結合に相当 var query = from contact in contacts join order in orders on contact.ContactID equals order.Contact.ContactID into contactGroup select new { ContactID = contact.ContactID, OrderCount = contactGroup.Count(), Orders = contactGroup.Select(order => order) }; VSUG DAY 2010.05.09
  • 31. LINQ to Entities クエリ式の構文例(グループ化) var query = ( from contact in contacts group contact by contact.LastName.Substring(0, 1) into contactGroup select new { FirstLetter = contactGroup.Key, ContactGroup = contactGroup }). OrderBy(letter => letter.FirstLetter); foreach (var contact in query) { Console.WriteLine("Last names that start with the letter '{0}':", contact.FirstLetter); foreach (var name in contact.ContactGroup) { Console.WriteLine(name.LastName); } } VSUG DAY 2010.05.09
  • 32. 関連オブジェクトの読み込み 読み込みパターン 説明 クエリで指定する ナビゲーション プロパティを使用 明示的読み込み Loadメソッドを使用 遅延読み込み LazyLoadingEnabledプロパティをtrueにセット 一括読み込み ObjectQuery で Include(String) メソッドを使用 VSUG DAY 2010.05.09
  • 33. 関連するオブジェクトを明示的に読み込む Contact customer = context.Contacts .Where("it.ContactID = @customerId", new ObjectParameter("customerId", customerId)).First(); if (!customer.SalesOrderHeaders.IsLoaded) { customer.SalesOrderHeaders.Load(); } foreach (SalesOrderHeader order in customer.SalesOrderHeaders) { if (!order.SalesOrderDetails.IsLoaded) { order.SalesOrderDetails.Load(); } VSUG DAY 2010.05.09
  • 34. 遅延読み込み Entity Framework ツールを使用して新しいモデルおよび 対応する生成済みクラスを作成する場合、 LazyLoadingEnabled の既定値は true context.ContextOptions.LazyLoadingEnabled = true; 遅延読み込みは、単一オブジェクト (EntityReference な ど) とオブジェクトのコレクション (EntityCollection な ど) の両方を返すナビゲーション プロパティでサポート 遅延読み込みが有効であっても、関連オブジェクトが既 に読み込まれているなら、関連オブジェクトが再度読み 込まれることはない 遅延読み込みは、Detached() 状態にあるオブジェクトで サポートされる。この場合、関連オブジェクトも Detached() 状態で返される VSUG DAY 2010.05.09
  • 35. 一括読み込み(クエリ パスの定義) var contacts = (from contact in context.Contacts .Include("SalesOrderHeaders.SalesOrderDetails") select contact).FirstOrDefault(); try { foreach (SalesOrderHeader order in contacts.SalesOrderHeaders) { Console.WriteLine(String.Format("PO Number: {0}", order.PurchaseOrderNumber)); Console.WriteLine(String.Format("Order Date: {0}", order.OrderDate.ToString())); Console.WriteLine("Order items:"); foreach (SalesOrderDetail item in order.SalesOrderDetails) { Console.WriteLine(String.Format("Product: {0} " + "Quantity: {1}", item.ProductID.ToString(), item.OrderQty.ToString())); } } VSUG DAY 2010.05.09
  • 37. オブジェクトの作成と追加 using (ChinookEntities context = new ChinookEntities()) { ObjectSet<Artist> artists = context.Artists; //ArtistIdはIdentityとして宣言されているので、初期値(0)は無視される Artist artist = Artist.CreateArtist(0); artist.Name = "Atsushi Fukui"; artists.AddObject(artist); context.SaveChanges(); Console.WriteLine("Added Artist id {0} name {1}", artist.ArtistId, artist.Name); VSUG DAY 2010.05.09
  • 38. オブジェクトの削除 using (ChinookEntities context = new ChinookEntities()) { ObjectSet<Artist> artists = context.Artists; Artist artist = artists.Where("it.Name=@name", new ObjectParameter("name", "Atsushi Fukui")).First(); if (artist != null) { artists.DeleteObject(artist); context.SaveChanges(); } } VSUG DAY 2010.05.09
  • 39. オブジェクトの更新 object entity = null; IEnumerable<KeyValuePair<string, object>> keyValues = new KeyValuePair<string, object>[]{ new KeyValuePair<string, object>("ArtistId", 279) }; EntityKey key = new EntityKey("ChinookEntities.Artists", keyValues); if (context.TryGetObjectByKey(key, out entity)) { Artist artist = (Artist)entity; artist.Name = "Hideharu Moriya"; context.SaveChanges(); } Artist a = context.Artists.Where(o => o.ArtistId == 279).First(); if (a != null) { Console.WriteLine(“artist id {0}, name {1}”, a.ArtistId, a.Name); } VSUG DAY 2010.05.09
  • 40. ID管理、状態管理、変更の追跡 ObjectStateEntry  アタッチされている各オブジェクトに対して作成さ れる  EntityKey と EntityState、関連するオブジェクトに関 する情報、およびオブジェクトのプロパティの元の 値と現在の値を格納  エンティティがデタッチされると、対応する ObjectStateEntry オブジェクトがオブジェクト コンテ キストから削除される  ObjectStateManager によって管理される  各オブジェクト コンテキストについて、 ObjectStateManager のインスタンスが 1 つ存在 VSUG DAY 2010.05.09
  • 41. エンティティ状態 マージ 説明 オプション Added 新しいオブジェクトがオブジェクト コンテキストに追加されている。 SaveChanges() メソッドは呼び出されていない。変更が保存されると、 オブジェクトの状態は Unchangedに変更される。 Deleted オブジェクトがオブジェクト コンテキストから削除されている。変更 が保存されると、オブジェクトの状態は Detachedに変更される。 Detached オブジェクトが存在するが追跡されていない。エンティティは、作成さ れた直後とオブジェクト コンテキストに追加される直前にこの状態に なる。また、Detach(Object) メソッドを呼び出してコンテキストから削 除された後、または NoTracking MergeOption を使用して読み込まれる 場合にもこの状態になる。 Modified オブジェクトのスカラー プロパティのいずれかが変更されている。 SaveChangesメソッドは呼び出されていない。変更追跡プロキシを持た ない POCO エンティティでは、DetectChangesメソッドが呼び出された ときに、変更されているプロパティの状態が Modified に変わる。変更 が保存されると、オブジェクトの状態は Unchangedに変わる。 Unchanged オブジェクトは、コンテキストに読み込まれた後、または最後に SaveChanges メソッドが呼び出されてから変更されていない。 VSUG DAY 2010.05.09
  • 42. 変更の追跡 Entity Framework により生成されたエンティティおよび変更追跡プ ロキシ オブジェクトを持つ POCO エンティティに対しては、 ObjectStateEntry はオブジェクト プロパティの現在の値および変更 されたプロパティの元の値を格納する Added 状態または Detached 状態にあるオブジェクトは、元の値を 保持していない オブジェクト コンテキストは、プロパティが変更されると通知を受 け取り、ObjectStateEntry 内のオブジェクトの状態とプロパティの 値を更新する ObjectStateEntry は、変更追跡プロキシの無いPOCOエンティティ、 および複合型オブジェクトでは異なる方法で管理する。これらの型 のオブジェクトに対し、ObjectStateEntryは、オブジェクトが最初 にコンテキストに入った時にオブジェクト プロパティの値のスナッ プショットを取得し、元の値のセットと現在の値のセットを格納す る。 VSUG DAY 2010.05.09
  • 43. ID解決とマージ 特定のエンティティ キーを持つオブジェクトの 1 つのみのインスタンスをキャッシュ内に保持 する 同じ ID を持つエンティティが既に追跡されてい る場合、データ ソースからのデータと状態マ ネージャーに既に存在するデータは、クエリの MergeOption に従ってマージされる var orders = Customer.Orders.Execute(MergeOption.PreserveChanges); VSUG DAY 2010.05.09
  • 44. マージ オプション マージ オプション 説明 AppendOnly オブジェクト コンテキストに存在しないオブジェクトは、コンテキストに アタッチされる。オブジェクト コンテキストに存在するオブジェクトのプ ロパティは、データ ソースの値によって上書きされない。AppendOnly() は既定のマージ オプション OverwriteChanges オブジェクト コンテキストに存在しないオブジェクトは、コンテキストに アタッチされる。オブジェクト コンテキストに存在するオブジェクトのプ ロパティは、データ ソースの値によって上書きされる。 PreserveChanges .NET Framework バージョン 3.5 SP1 では、オブジェクト コンテキスト内 のオブジェクトのプロパティ値がサーバー上の値と異なる場合、オブジェ クト コンテキスト内のプロパティ値は、オブジェクトが Unchanged状態 にない限り、保持される。Unchanged状態の場合は、プロパティがデータ ソースの値で上書きされる。 .NET Framework バージョン 4 では、オブジェクト コンテキスト内のオブ ジェクトの値はすべて、オブジェクトの状態にかかわらず保持される。 NoTracking オブジェクトは、Detached状態で保持され、ObjectStateManager では追 跡されない。ただし、Entity Framework により生成されたエンティティお よびプロキシを持つ POCO エンティティは、関連するオブジェクトの読み 込みを容易にするために、オブジェクト コンテキストへの参照を保持する。 VSUG DAY 2010.05.09
  • 45. 同時実行制御チェック ConcurrencyMode=“Fixed” を使用すると Entity Framework は、変更をデータベース に保存する前に、データベース内の変更 をチェックする SQL Serverの場合、各テーブルにタイムス タンプ列を追加して指定すると良い 他のデータベースの場合はトリガでタイムス タンプを更新するなど VSUG DAY 2010.05.09
  • 46. 同時実行制御チェック VSUG DAY 2010.05.09
  • 48. Entity Data Model: 継承 概念モデルでは派生型は基本型のすべてのプロ パティとナビゲーション プロパティを継承 ルート型はエンティティ キーを定義する必要が ある 単一継承のみ可能 CSDLによる定義例 <EntityType Name="FictionBook" BaseType="BooksModel.Book" > <Property Type="String" Name="Genre" Nullable="false" /> </EntityType> VSUG DAY 2010.05.09
  • 49. 概念モデルの継承の実装方式 Table-Per-Type継承  概念スキーマで派生型のBaseType属性に基本エンティティ型を 指定  基本エンティティを抽象型として定義  派生型のIDを削除  マッピングの詳細ウィンドウでIDを基本エンティティのIDに マップ Table-Per-Hierarchy 継承  概念スキーマで派生型のBaseType属性に基本エンティティ型を 指定  マッピングの詳細ウィンドウで「テーブルまたはビューの追 加」からテーブルを選択  条件の追加でプロパティにIs NullまたはIs Not Nullを設定 VSUG DAY 2010.05.09
  • 50. 自動生成されるSQLの一部 -- Creating table 'Parties' CREATE TABLE [dbo].[Parties] ( [Id] int IDENTITY(1,1) NOT NULL, [Name] nvarchar(max) NOT NULL ); GO -- Creating table 'Parties_Organization' CREATE TABLE [dbo].[Parties_Organization] ( [Location] nvarchar(max) NOT NULL, [Id] int NOT NULL ); GO -- Creating table 'Parties_Person' CREATE TABLE [dbo].[Parties_Person] ( [Age] int NOT NULL, [Id] int NOT NULL ); GO VSUG DAY 2010.05.09
  • 51. エンティティの継承 VSUG DAY 2010.05.09
  • 53. N層アプリケーションとは クライアント層、中間サービス層、デー タベース層に分かれる ASP.NETアプリケーション WCFサービス、Webサービスを利用するアプ リケーション Silverlightアプリケーション オブジェクトをシリアル化して他の層に 転送し逆シリアル化して利用 更新された情報を何らかの方法で保持す る必要がある VSUG DAY 2010.05.09
  • 54. オブジェクトのシリアル化 オブジェクトをシリアル化すると、EntityKey オブジェクトもシリ アル化される バイナリ シリアル化と WCF データ コントラクト シリアル化を使 用する場合に、シリアル化するオブジェクトのオブジェクト グラフ に関連オブジェクトがあると、これらのオブジェクトもシリアル化 される XML シリアル化では、関連オブジェクトはシリアル化されない オブジェクトのプロパティとリレーションシップ情報だけがシリア ル化される オブジェクト コンテキストで維持されているオブジェクトの状態情 報はシリアル化されない .NET Framework バージョン 4 から、自己追跡エンティティで独自 の変更追跡ロジックを利用できるようになった(後述) オブジェクトが逆シリアル化された後、オブジェクトは Detached() 状態になる VSUG DAY 2010.05.09
  • 55. オブジェクトのアタッチ、デタッチ Entity Framework では、オブジェクト コンテキスト内で クエリを実行すると、返されたオブジェクトがそのオブ ジェクト コンテキストに自動的にアタッチされる 以前にデタッチされているオブジェクト、NoTracking() クエリによって返されたオブジェクト、またはオブジェ クト コンテキストの外部で取得したオブジェクトなど もアタッチできる ASP.NET アプリケーションのビュー ステートに保存さ れていたオブジェクトや、リモート メソッド呼び出し または Web サービスによって返されたオブジェクトも アタッチできる VSUG DAY 2010.05.09
  • 56. 変更の適用(デタッチ オブジェクト) 単純にアタッチされた場合、そのオブジェクト が既にオブジェクト コンテキスト内にあると、 更新が失われるか、操作が失敗する (Unchanged状態でアタッチされるため) オリジナルのオブジェクトと変更後のオブジェ クトをクライアントから返してもらうことでオ ブジェクト コンテキストにアタッチしたオブ ジェクトに変更を適用する VSUG DAY 2010.05.09
  • 57. オブジェクトをアタッチするメソッド メンバー 説明 ObjectSetAddObject() オブジェクトとその関連オブジェクトを ObjectContext または に追加し、エンティティ オブジェクトを Added 状態に ObjectContextAddObject(S 設定します。この状態では、エンティティ オブジェクト tring, Object) の一意のキー値を持つ必要はない。一時的なキー値が キーのプロパティに割り当てられ、オブジェクトの保存 後にデータ ソースが生成した値で更新される。オブジェ クトを追加後、エンティティ オブジェクトの状態が適切 に変更される。 ObjectSetAttach() オブジェクトを ObjectContext に追加し、オブジェクト または を Unchanged 状態に設定する。Unchanged 状態では、 ObjectContextAttach(IEntit Entity Framework はエンティティ キーの値を最終版とし yWithKey) て処理する。特定の型の複数のエンティティに同じキー と の値がある場合は、Entity Framework は例外をスローす AttachTo(String, Object) る。例外を回避するには、AddObject メソッドを使用し てデタッチされたオブジェクトをアタッチし、適切な状 態に変更する。 VSUG DAY 2010.05.09
  • 58. アタッチして変更を適用する例 private static void ApplyItemUpdates( SalesOrderDetail originalItem, SalesOrderDetail updatedItem) { using (AdventureWorksEntities advWorksContext = new AdventureWorksEntities()) { try { //オリジナルのItemをオブジェクト コンテキストにアタッチ advWorksContext.Attach(originalItem); //変更を適用するためにApplyCurrentValuesメソッドを使用 advWorksContext.ApplyCurrentValues(“SalesOrderDetails”, updatedItem); advWorksContext.SaveChanges(); } catch (InvalidOperationException ex) { Console.WriteLine(ex.ToString()); } } } VSUG DAY 2010.05.09
  • 59. 自己追跡エンティティ VSUG DAY 2010.05.09
  • 60. 自己追跡エンティティ //クライアント側コード static void UpdateDepartmentAndCourses(int departmentID, int courseID) { using (var service = new Service1Client()) { List<Department> departments = service.GetDepartments(); Department department = departments.Single( d => d.DepartmentID == departmentID); department.Budget = department.Budget - 1000.00m; Course existingCourse = department.Courses.Single( c => c.CourseID == courseID); existingCourse.Credits = 3; service.UpdateDepartment(department); } } VSUG DAY 2010.05.09
  • 61. 自己追跡エンティティ //サービス側コード public void UpdateDepartment(Department updated) { using (SchoolEntities context = new SchoolEntities()) { try { context.Departments.ApplyChanges(updated); context.SaveChanges(); } catch (UpdateException) { throw; } } } VSUG DAY 2010.05.09
  • 62. まとめ ADO.NET Entity FrameworkはEDMの実装を提供 概念スキーマ定義とストア スキーマ定義をマッピング することでストアに非依存なモデルを利用可能  エンティティとアソシエーションの概念 同時実行制御チェックを有効にする オブジェクト状態を理解する N層アプリケーションと自己追跡エンティティ  WCF サービス アプリケーションとの連携  ObjectContextをサービス層でキャッシュするのはアンチパタン 継承エンティティによるテーブル マッピング その他  IObjectSetの利用によってテスト容易性が向上している VSUG DAY 2010.05.09
  • 63. 参考資料 Entity Framework を使用した n 層アプリケーションで回 避すべきアンチパターン http://msdn.microsoft.com/ja-jp/magazine/dd882522.aspx n 層アプリケーションのパターン http://msdn.microsoft.com/ja-jp/magazine/ee321569.aspx チュートリアル: ストアド プロシージャへのエンティ ティのマッピング http://msdn.microsoft.com/ja-jp/library/cc716679(v=VS.100).aspx Walkthrough: Serialize Self-Tracking Entities (Entity Framework) (英語) http://msdn.microsoft.com/en-us/library/ee789839(v=VS.100).aspx Entity Framework FAQ(英語) http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx VSUG DAY 2010.05.09
  • 65. Appendix VSUG DAY 2010.05.09
  • 66. EdmGen.exe コマンドラインによるオブジェクト レイ ヤ生成 C#のコード生成 "%windir%¥Microsoft.NET¥Framework¥v4.0.30319¥edmgen.exe" /mode:EntityClassGeneration /incsdl:.¥School.csdl /outobjectlayer:.¥School.Objects.cs /language:CSharp VBのコード生成 "%windir%¥Microsoft.NET¥Framework¥v4.0.30319¥edmgen.exe" /mode:EntityClassGeneration /incsdl:.¥School.csdl /outobjectlayer:.¥School.Objects.vb /language:VB VSUG DAY 2010.05.09
  • 67. 概念スキーマ 定義言語: EntityContainer … <EntityContainer Name="ChinookEntities“ annotation:LazyLoadingEnabled="true"> <EntitySet Name="Albums" EntityType="ChinookModel.Album" /> <EntitySet Name="Artists" EntityType="ChinookModel.Artist" /> <AssociationSet Name="FK__Album__ArtistId__108B795B“ Association="ChinookModel.FK__Album__ArtistId__108B795B" > <End Role="Artist" EntitySet="Artists" /> <End Role="Album" EntitySet="Albums" /> </AssociationSet> </EntityContainer> … VSUG DAY 2010.05.09
  • 68. 概念スキーマ 定義言語: EntityType … <EntityType Name="Album"> <Key> <PropertyRef Name="AlbumId" /> </Key> <Property Name="AlbumId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" /> <Property Name="Title" Type="String" Nullable="false" MaxLength="160" Unicode="true" FixedLength="false" /> <Property Name="ArtistId" Type="Int32" Nullable="false" /> <NavigationProperty Name="Artist“ Relationship="ChinookModel.FK__Album__ArtistId__108B795B“ FromRole="Album" ToRole="Artist" /> </EntityType> … VSUG DAY 2010.05.09
  • 69. 概念スキーマ 定義言語: Association … <Association Name="FK__Album__ArtistId__108B795B"> <End Type="ChinookModel.Artist" Role="Artist" Multiplicity="1" /> <End Type="ChinookModel.Album" Role="Album" Multiplicity="*" /> <ReferentialConstraint> <Principal Role="Artist"> <PropertyRef Name="ArtistId" /> </Principal> <Dependent Role="Album"> <PropertyRef Name="ArtistId" /> </Dependent> </ReferentialConstraint> </Association> … VSUG DAY 2010.05.09
  • 70. ストア スキーマ 定義言語: EntityContainer … <EntityContainer Name="ChinookModelStoreContainer"> <EntitySet Name="Album“ EntityType="ChinookModel.Store.Album" store:Type="Tables" Schema="dbo" /> <EntitySet Name="Artist" EntityType="ChinookModel.Store.Artist" store:Type="Tables" Schema="dbo" /> <AssociationSet Name="FK__Album__ArtistId__108B795B" Association="ChinookModel.Store.FK__Album__ArtistId__108B7 95B"> <End Role="Artist" EntitySet="Artist" /> <End Role="Album" EntitySet="Album" /> </AssociationSet> </EntityContainer> … VSUG DAY 2010.05.09
  • 71. ストア スキーマ 定義言語: EntityType … <EntityType Name="Album"> <Key><PropertyRef Name="AlbumId" /></Key> <Property Name="AlbumId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="Title" Type="nvarchar" Nullable="false" MaxLength="160" /> <Property Name="ArtistId" Type="int" Nullable="false" /> </EntityType> <EntityType Name="Artist"> <Key><PropertyRef Name="ArtistId" /></Key> <Property Name="ArtistId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="Name" Type="nvarchar" MaxLength="120" /> </EntityType> … VSUG DAY 2010.05.09
  • 72. ストア スキーマ 定義言語: Association … <Association Name="FK__Album__ArtistId__108B795B"> <End Role="Artist" Type="ChinookModel.Store.Artist" Multiplicity="1" /> <End Role="Album" Type="ChinookModel.Store.Album" Multiplicity="*" /> <ReferentialConstraint> <Principal Role="Artist"> <PropertyRef Name="ArtistId" /> </Principal> <Dependent Role="Album"> <PropertyRef Name="ArtistId" /> </Dependent> </ReferentialConstraint> </Association> … VSUG DAY 2010.05.09
  • 73. マッピング 仕様言語: EntityMapping … <EntitySetMapping Name="Albums"> <EntityTypeMapping TypeName="ChinookModel.Album"> <MappingFragment StoreEntitySet="Album"> <ScalarProperty Name="AlbumId" ColumnName="AlbumId" /> <ScalarProperty Name="Title" ColumnName="Title" /> <ScalarProperty Name="ArtistId" ColumnName="ArtistId" /> </MappingFragment> </EntityTypeMapping> </EntitySetMapping> … VSUG DAY 2010.05.09
  • 74. データベースへの接続 以下の場合に自動的に接続  ObjectContext に対する SaveChanges()、または Refresh(RefreshMode, IEnumerable)  ObjectQuery に対する FirstOrDefault(IEnumerable<UMP>)、ま たは First(IEnumerable<UMP>)  EntityCollection に対する Load(MergeOption)  EntityReference に対する Load(MergeOption)  任意の統合言語クエリ (LINQ) メソッドまたは ObjectQuery クエ リ ビルダー メソッド (Where(String, ObjectParameter[])、 OrderBy(String, ObjectParameter[])、Select(String, ObjectParameter[]) など)  接続は、ObjectResult が完全に消費されるか破棄されるまで開 いたままになる VSUG DAY 2010.05.09
  • 75. 接続を手動で開く using (AdventureWorksEntities advWorksContext = new AdventureWorksEntities()) { try { //明示的に接続を開く advWorksContext.Connection.Open(); // オーダーを返すクエリを実行 SalesOrderHeader order = advWorksContext.SalesOrderHeaders.Where( "it.SalesOrderID = @orderId", new ObjectParameter("orderId", orderId)) .Execute(MergeOption.AppendOnly).First(); order.Status = 1; // 変更を保存 if (0 < advWorksContext.SaveChanges()) { Console.WriteLine("Changes saved."); } } catch (InvalidOperationException ex) { Console.WriteLine(ex.ToString()); } // オブジェクト コンテキストがDisposeされるときに接続は閉じられる } VSUG DAY 2010.05.09