まだ生きているようです

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
-------- : スポンサー広告 :
Pagetop

EntityFramework:いろいろなマッピングの例3

今回は多対多表現です。これも結構情報は出ていますので、簡単に書いてみます。

 

9/25にお話した例は、インストラクターエンティティと、授業エンティティが存在していて、インストラクターは複数の授業を担当することを表現したい場合の話でした。

その場合、テーブルは以下のような形になるかと思います。

20101002_EF7

中間テーブルである、CourseInstructorを通じて、1対多関係でリレーションを表現します。

 

これをEDMの概念モデルで表現すると以下のように表すことが可能です。

20101002_EF8

概念モデルの表現として、CourseInstructorテーブルはエンティティではなくて、アソシエーションにすることが可能です。(DataBase Firstの場合は、自動的に上記の形になります)

エンティティにするか、アソシエーションにするかは結構議論の分かれるところですが、上記の場合は、コードは以下のように書きます。

using (SchoolEntities db = new SchoolEntities())

{

    var query = from c in db.Courses

                      from p in c.People

                      where p.FirstName == "Roger"

                      select c;

    foreach (var q in query)

    {

        Console.WriteLine(q.Title);

    }

}

fromが2回連続で出てきますので、ちょっと気持ち悪い感じがするかもしれません。

図にすると、以下のようなイメージになります。

 

20101002_EF9

2回選択している雰囲気が伝わるでしょうか?

この手のクエリはLINQであれば、LINQ to XMLなんかで使用されることが多いですよね。

このシリーズ書いていて思いますが、セッションで話したことをもう一度書くのは、結構苦痛です(笑)

tag : EntityFramework

2010-10-02 : EntityFramework : コメント : 0 : トラックバック : 0
Pagetop

EntityFramework:いろいろなマッピングの例2

今回は継承について紹介します。

Entity Data Modelでは、以下2種類の継承が可能です。
・Table-Per-Type (TPT)
・Table-Per-Hierarchy (TPH)

継承を使用すると、概念モデルをよりオブジェクト指向的に定義する事が可能になりますが、エンティティとテーブルスキーマの考え方が別物になるなど、当然トレードオフがあるので注意が必要です。

・Table-Per-Type (TPT)
エンティティにマップされる、別個のテーブルを使用して、非継承プロパティと継承階層のそれぞれの型のキー、プロパティのデータを維持する方法です。と書いても意味が分かりにくいので下図をご確認下さい。

20101002_EF1.jpg

・Table-Per-Hierarchy (TPH)
1 つの テーブルを使用して、継承階層のすべてのエンティティ型のデータを維持する方法です。単一テーブル継承とも呼ばれます。こちらも下図をご確認ください。

20101002_EF2.jpg

TPHを実現するには、多少の手順が必要になります。

例えば、DataBase Firstで以下のようなエンティティが出来上がったとします。
20101002_EF3.jpg
このエンティティは、Employeesテーブルがもとになっていて、ユースケースとして、Employeeのほかに、OperatorとAdministratorと言うアクターが存在し、Employeesテーブルに一緒に保存されている状況です。

そこで、OperatorエンティティとAdministratorエンティティを作成します。(親のエンティティはemployeeにします)

20101002_EF4.jpg

次に、Operator(Administrator)にしかない情報(スカラプロパティ)を親のemployeesから切り取り⇒貼り付けを行います。
また、employeeFlgも削除してしまいます。その結果以下のようになります。

20101002_EF5.jpg

employeeFlgが0の場合はemployee、1の場合はOperator、2の場合はAdministratorというルールを実現したいので、マッピングの詳細をそれぞれ3つのエンティティクラス上で行います。(下図はAdministratorのマッピングです)
20101002_EF6.jpg

これでEDMの作成は終了です。

コードは以下のようになります。(このコードは、TPT、TPH双方で使用することが可能です。)
この例は、Employee1人、Operator1人、Administrator1人を追加して、Operatorを全員抽出しています。
using (Demo2Entities db = new Demo2Entities())
{
     employee newEmployee = new employee();
     newEmployee.ID = 11;
     newEmployee.Name = "社員1";
     db.employees.AddObject(newEmployee);

     Operator newOperator = new Operator();
     newOperator.ID = 502;
     newOperator.Name = "オペレーター1";
     newOperator.Ope_Desc = "オペレーター用の備考";
     db.employees.AddObject(newOperator);

     Administrator newAdministrator = new Administrator();
     newAdministrator.ID = 302;
     newAdministrator.Name = "管理者1";
     newAdministrator.Admin_Desc = "管理者用の備考";
     db.employees.AddObject(newAdministrator);

     db.SaveChanges();

      var query = from o in db.employees.OfType<employee>()
                          select o;

     foreach (var q in query)
     {
          Console.WriteLine(q.Name);
     }
}

ちなみに、Model First での継承は、必然的にTPTになるはずです。
(ただし、TPHが絶対不可能なわけではありません)
また、Database First での継承は、テーブルスキーマーによってTPTとTPHを使い分けることになります。
ただ、TPHは実テーブルスキーマから乖離するので注意が必要ですね。


テーマ : プログラミング
ジャンル : コンピュータ

tag : EntityFramework

2010-10-02 : EntityFramework : コメント : 0 : トラックバック : 0
Pagetop

セッション資料が公開されました

9/25にお話した資料が公開されました。

こんなタイトルと概要です。
「Entity Framework開発のTips集」
「Entity Frameworkはなんとなく分かっています」と言う人を対象に、概要から少し踏み込んだ内容をお話します。と言っても、内部の複雑なアーキテクチャなどではなく、EFが出来る事で、これまであまり話されてこなかった内容をお届けしたいと思います。

ご興味のある方はこちらから。

フォロー記事も随時書いていきますね。


テーマ : 独り言
ジャンル : 日記

tag : EntityFramework お知らせ

2010-09-30 : お知らせ : コメント : 0 : トラックバック : 0
Pagetop

EntityFramework:いろいろなマッピングの例1

9/25に話した内容の一部です。

MSDNライブラリあたりには書いてある既知の内容なのですが、一応書いてみます。

今回は、概念モデルのいろいろな形を紹介します。

 

まずは、単一のエンティティを複数のテーブルにマップする方法です。

これはテーブルを(RDB上の何らかの事情で)、複数に分割していて、概念モデルでは一つで扱いたい場合などに便利です。

 

図で表すと以下のようなイメージです。

 20100926_EF1

手順といっても、デザイナで簡単に実現可能ですので、おおざっぱに。

上図の場合、employee2テーブルとemployee2_1テーブルから、DataBase Firstで、下記のように2つのエンティティがデザイナ上にできます。

20100926_EF2

 

employee2_1エンティティのData10~Data15を切り取って、employee2エンティティに貼り付けます。

20100926_EF3

 

すると結果以下のようになるので、、、

20100926_EF4

マッピングを以下のように変更します。

ここで2つのテーブルに関連づけられます。

20100926_EF5

最後に、あまったemployee2_1エンティティを削除します。

 

コードも紹介しておきます。と言っても普通ですけど。

社員を一人追加します。

using (Demo2Entities db = new Demo2Entities())
{
    employees2 newEmployee = employees2.Createemployees2(10, "社員1");
    newEmployee.Data1 = "Data1";
    newEmployee.Data13 = "Data13";
    db.employees2.AddObject(newEmployee);
    db.SaveChanges();
}

 

ちゃんと2つのテーブルに振り分けられてデータが追加されます。

20100926_EF6

 

注意する点は、2つのテーブルが1:1の対応になっていること(リレーションがなくてもOK)と、キーの形が同じことが条件になることです。

テーマ : プログラミング
ジャンル : コンピュータ

tag : EntityFramework

2010-09-26 : EntityFramework : コメント : 0 : トラックバック : 0
Pagetop

EntityFrameworkでのストアドプロシージャコール2

前回の続きで、EntityFrameworkでのストアドプロシージャコールです。

今回はEntity Clientで考えてみたいと思います。

結果セット、引数、リターンコードを一度に照会したいので、以下のようなストアドプロシージャを使用します。
CREATE PROCEDURE [dbo].[byroyalty]
@percentage int,
@arg nvarchar(50) output
AS
select au_id from titleauthor
where titleauthor.royaltyper = @percentage

SELECT @arg = 'テスト'
RETURN 1

呼び出し側のコードは以下のようになります。
using (pubsEntities db = new pubsEntities())
{
    db.Connection.Open();
    DbCommand command = db.Connection.CreateCommand();
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "pubsEntities.byroyalty";
    command.Parameters.Add(new EntityParameter("percentage", DbType.Int32)
                      { Direction = ParameterDirection.Input, Value = 40 });
    command.Parameters.Add(new EntityParameter("arg", DbType.String)
                      { Direction = ParameterDirection.Output , Value = "" });
    command.Parameters.Add(new EntityParameter("ReturnValue", DbType.Int32)
                      { Direction = ParameterDirection.ReturnValue });
    DbDataReader dr =
        command.ExecuteReader(CommandBehavior.SequentialAccess);
    while (dr.Read())
    {
        Console.WriteLine("結果セット:" + dr[0]);
    }
    dr.Close();
    int? returnValue = ((int?)command.Parameters["ReturnValue"].Value);
    Console.WriteLine("戻り値:" + returnValue.ToString());

    string arg = ((string)command.Parameters["arg"].Value);
    Console.WriteLine("Output引数:" + arg);
}

むぅ、長いです。ただ通常のADO.NETでも同じでしたので、単に普段リポジトリとかで楽をし過ぎているのでしょう(笑)

結果は以下のようになります。
20100924_EF4.jpg

リターンコードまで取得できているのが分かりますね。
さて、注意点ですが、.ExecuteReaderは、SequentialAccessオプションが必須になります。
また、ADO.NETと同様に、DataReaderをCloseしなければ、リターンコードとOutput引数の値は取得することが出来ないようになっています。
後は、DataReaderでの結果セットの取得になりますので、その後EntityClassで取り扱いたい場合は、何らかの手段を講じる必要が出てきますよね。

記述量も多くて多少面倒ですし、Object Servicesと使い分ける必要がありそうです。

前回の記事も含めて、あまり面白い話になりませんでした。。。

テーマ : プログラミング
ジャンル : コンピュータ

tag : EntityFramework

2010-09-24 : EntityFramework : コメント : 0 : トラックバック : 0
Pagetop
« 前のページ  ホーム  次のページ »

カレンダー

プルダウン 降順 昇順 年別

07月 | 2017年08月 | 09月
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -


カテゴリ

openclose

タグクラウドとサーチ

メールフォーム

名前:
メール:
件名:
本文:

プロフィール

こだかたろう

元MSの小高と申します。
(↓こんな人です。)
こんな見た目です

ずっとエバンジェリストをしていましたが、この度転身いたしました。
よろしくどうぞ。

Select Template

RSSリンクの表示

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。