LINQ to SQL 備忘録1、備忘録2、備忘録3に続いて、本気時ではコマンドラインツール SQLMetal.exe と Visual Studio 2008 に付属する Object Relational Designer を使用してみます。

確認環境

  • Windows Vista Enterprise
  • Visual Studio 2008 Professional
  • .NET 3.5

使用するデータベースは AdventureWorks を使用しています。

サンプルデータベースAdventureWorksの構築を参照して下さい。

1. SQLMetal コマンドラインツール

SQLMetal を使用して、DBML ファイル、 Entity クラス、 マッピングファイルを作成します。SQLMetal は Visual Studio 2008 Command Prompt を使用して実行します。Visual Studio 2008 Command Prompt はスタート->All Programs->Microsoft Visual Studio 2008->Visual Studio Tools を順に移動し、VIsual Studio 2008 Command Prompt を選択して起動します。

SQLMetail を使用すると以下のことが行えます。SQLMetalのヘルプはコマンドプロンプト上でSQLMetal  /? と入力して表示できます。

  • データベースから DBML ファイルを生成する
  • データベースからエンティティクラスのソースを生成する。(オプションによりマッピングファイルも作成可能)
  • DBML ファイルからエンティティクラスを作成する。(オプションによりマッピングファイルも作成可能)

SQLMetal のコマンドライン構文は次のようになります。

sqlmetal  <オプション>  <入力ファイル>

1.1 データベースから DBML ファイルを作成する

DBML ファイルを作成する場合は、次のようにコマンドプロンプト上で入力します。現在ログインしているユーザで SQL Server にログインします。/server オプションで SQL Server のインスタンス名を指定します。 /databse オプションで DBML ファイルを作成する データベースを指定します。

sqlmetal /server:localhost\sqlexpress /database:AdventureWorks /dbml:adventureworks.dbml

ログインユーザ以外で Windows 認証を使用して SQL Server にログインする場合は、次のように /user , /password オプションを使用します。

sqlmetal /server:localhost\sqlexpress /database:AdventureWorks /user:【ユーザID】 /password:【パスワード】 /dbml:adventureworks.dbml

SQL Server 認証を使用して SQL Server にログインし、DBML ファイルを使用する場合は、 /conn オプションを使用して接続文字列を直接指定することで行います。

sqlmetal /conn:"Data Source=.\SQLEXPRESS;Initial Catalog=AdventureWorks;User ID=【ユーザID】;Password=【パスワード】" /dbml:adventureworks.dbml

接続文字列を"Data Source=.\SQLEXPRESS;Initial  Catalog=AdventureWorks;Integrated Security=yes"のように指定することで Windows 統合認証を使用するように接続文字列で指定することもできます。

mdf ファイルを使用している場合、sdf ファイルを使用している場合、同様に作成できます。

sqlmetal  /dbml:AdventureWorks.dbml  AdventureWorks.mdf
sqlmetal /dbml:AdventureWorks.dbml  AdventureWorks.sdf

既定ではデータベースのテーブル情報のみ DBML ファイルに作成されるが、ストアドプロシージャ、ファンクション、ビュー情報を持つDBMLファイルを作成することもできます。その場合は /views, /functions, /sprocs オプションを指定します。以下にサンプルを掲載します。

sqlmetal  /server:localhost\sqlexpress /database:AdventureWorks /sprocs /functions /views /dbml:adventureworks.dbml

1.2 データベースからエンティティクラスのソース, マッピングファイルを生成する

データベースから直接エンティティクラスのソースファイルを作成するとき場合は、/dbmlではなく、/code:オプションを使用します。DBML ファイルを作成したときと同様に、  /views, /functions, /sprocs オプション を指定すると、ビューのエンティティクラスとストアド、ファンクションを呼び出すメソッドが DataCOntext 継承クラスに定義されます。

sqlmetal  /server:localhost /database:AdventureWorks  /code:AdventureWorks.cs

SQL Server 認証を行う場合は、接続文字列を指定して次のように入力します。

sqlmetal /conn:"Data Source=.\SQLEXPRESS;Initial Catalog=AdventureWorks;User ID=【ユーザID】;Password=【パスワード】" /code:AdventureWorks.cs

マッピングファイルを作成する場合は、 /map: オプションを指定します。マッピングファイルを作成すると、エンティティクラスに TableAttribute などのマッピング情報の属性がソースファイルに作成されなくなります。

sqlmetal /server:localhost /database:AdventureWorks /code:AdventureWorks.cs /map:AdventureWorks.xml

ソースコードを生成すると、拡張点を提供するメソッドがデータコンテキスト継承クラスやエンティティクラスに作成されます。例えば下記のようなメソッドです。パーシャルクラスで以下のメソッドを実行すると、Person_Address エンティティが登録、更新、削除時に呼び出されるようになります。

  partial void InsertPerson_Address(Person_Address instance);
  partial void UpdatePerson_Address(Person_Address instance);
  partial void DeletePerson_Address(Person_Address instance);

上記のpartial が修飾されたメソッドはパーシャルクラスで定義されなければ、実行時に無視されます。

1.3 DBML ファイルからエンティティクラスのソースコード、マッピングファイルを作成する

DBMLファイルからソースファイルを生成する場合、以下のように入力します。作成されたファイルには各エンティティクラスと、データコンテキストを継承したクラスが定義されます。

sqlmetal /code:AdventureWorks.cs AdventureWorks.dbml

ソースファイルとマッピングファイルを生成する場合は、次のように入力します。

sqlmetal /code:AdventureWorks.cs /map:AdventureWorks.xml AdventureWorks.dbml

1.4 そのほかのオプション

/serialization 既定で None ,Unidirectional を指定すると DataContract が付与されたエンティティクラスが生成されます。
/namespace 自動生成されうクラスの名前空間を指定します。既定では名前空間はありません。
/entitybase エンティティクラスの基本クラスを指定できます。
/context  DataContext を継承して作成される DataContext 継承クラスのクラス名
/language 生成されるコードの言語を指定します。既定ではコードの拡張子で判定されます。VB,C#を指定できます。
/pluralize DataContext を継承したクラスのプロパティ名の命名規則を変更します。設定すると複数形のsが付与されます。(下記参照)

pluralize を設定すると下記のような生成されるコード(DataContext 継承クラス)のプロパティに複数形のsが付与されるかの違いが発生します。

// pluralize オプションをつけない場合
public System.Data.Linq.Table<Person_Contact> Person_Contact
{
    get
	{
		return this.GetTable<Person_Contact>();
    }
}
// pluralize オプションをつけた場合
public System.Data.Linq.Table<Person_Contact> Person_Contacts
{
    get
    {
        return this.GetTable<Person_Contact>();
    }
}

2. Object Relational Designer を使用する

Object Relational Designer は Visual Studio 2008 に統合されたグラフィカルエディタです。 グラフィカルエディタを使用して Entity クラスの作成、編集操作をすることで DBML ファイルを編集します。

2.1 DBML ファイルを作成

Object Relational Designer を起動するにはまず、プロジェクトを右クリック→Add→New Item で Add New Item ダイアログを表示し、 LINQ to SQL Classes テンプレートを選択して DBML ファイルを作成します。下図では、 AdventureWorks.dbml を入力しています。 AdventureWorks.dbml, AdventureWorks.dbml.layout, AdventureWorks.designer.cs が作成されます。

関連するファイルが作成された後、AdventureWorks.dbml ファイルを選択すると、下図のように Object Relational Designer が表示されます。

 

2.2 Entity クラス、ストアドプロシージャの作成

Server Explorer からテーブルをドラッグアンドドロップするか、Toolbox から Class, Association, Inheritance をドラッグしてEntity を作成できます。 Entity クラスはデザイナの左のペインにドラッグアンドドロップをして作成します。ストアドプロシージャやファンクションはデザイナの右のペインにドラッグアンドドロップします。図は、Server Explorer から ContactテーブルとSalesOrderHeaderテーブルをドラッグアンドドロップし、 ufn_ToYen メソッドをAdventureWorks.dbmlに追加した状態です。関連はテーブル定義に従って自動で作成されます。 Toolbox の Associationを使用して定義を手動で作成することもできます。

 

 

Association (矢印) を選択すると関連を確認、編集できます。

DataContext 継承クラスに拡張用のメソッドなどを定義する場合は別ファイルにパーシャルクラスとして定義します。ソリューションエクスプローラ上のdbmlファイルを選択し、Solution Explorer上部の View Code ツールバーを選択すると、今回の例ではパーシャルクラス用のファイル AdventureWorks.cs が自動生成されます。

2.3 デザイナ上で編集できるプロパティに作成

デザイナ上の Properties ウィンドウ上で編集できるいくつかのプロパティを説明します。 

DataContext 継承クラスのデザイナプロパティ(デザイナの任意の場所を選択すると選択されます)

Access データコンテキスト継承クラスのアクセス修飾子。既定で public 。
Base Class DataContext 継承クラスの基本クラス。既定で System.Data.Linq.DataContext  。
Context Namespace 生成するDataContext 継承クラスのみのネームスペースを指定します。エンティティ クラスの名前空間には影響がありません。
Entity Namespace 生成されるエンティティクラスの名前空間。データコンテキスト継承クラスには適用されない。
Inheritance Modifier 継承修飾子を指定できます。既定で(None)です。 abstract, sealed を選択できます。
Name DataContext 継承クラスのクラス名。既定ではデータベース名+ "DataContext"。
Serialization Mode Unidirectional に設定すると Entity クラスとプロパティに DataContract, DataMember が付与されます。既定では None が設定されます。

Entity クラスのデザイナプロパティ(デザイナ上で Entity クラス選択します)

Access アクセス修飾子を設定します。既定でpublic。public, internal を選択可能。
Inheritance Modifier 継承修飾子(None, abstract, selaed) を設定できます。既定は(None)です。
Name エンティティクラス名 デザイナ上でEntityクラスのメンバを選択するとProperties Windows でプロパティを設定できます。

Entity クラスのメンバのデザイナプロパティ(デザイナ上で Entity クラスの編集するメンバを選択します)

Access  アクセス修飾子。既定値はpublic で public, protected, protected internal, internal, private から選択可能。
Delay Loaded 既定値はfalse.trueにするとプロパティに最初にアクセスされたときにデータを取得するプロパティに対する遅延ロードが有効になります。フィールドの型はLink <T>として定義されます。
 Inheritance Modifier 継承修飾子を選択できます。(None), new, virtual, overrideを選択できます。既定で(None)です。
Name プロパティ名です。
Type プロパティの型です。
Auto Geenerated Value ColumnAttribute の IsDbGenerated に対応するプロパティ値です。
Auto Sync ColumnAttribute の AutoSync に対応するプロパティ値です。
 Nullable   true とするとプロパティがプリミティブ型のプロパティがNullableとして宣言されます。
Primary Key ColumnAttribute の IsPrimaryKey に対応するプロパティ値です。
Read Only  true を設定すると、 get アクセッサのみ定義されます。
Server Data Type ColumnAttribute の DbType に対応するプロパティ値です。
Source データベースのテーブルのカラム名です。ColumnAttribute の Name に対応するプロパティ値です。
Time Stamp ColumnAttribute の IsVersion に対応するプロパティ値です。
UpdateCheck ColumnAttribute のUpdateCheck に対応するプロパティです。

 Association デザイナプロパティ(デザイナ上で関連を選択します)

Cardinality 親から子への関連のカーディナリティを定義します。既定では OneToMany (一対多) です。OnetoMany 以外に、 OneToOne を選択できます。設定によって親 Entity クラスないの子クラスのプロパティの定義が変化します。(設定により EntityRef か EntitySet になります)。
Child Property 親クラスで定義された子 Entity クラスを現すプロパティのアクセス修飾子です。既定値は public で、public, Internal から選択できます。
Child Property - Access 親クラスで定義された子 Entity クラスを現すプロパティのプロパティ名です。
Child Property - Inheritance Modifier 親クラスで定義された子 Entity クラスを現すプロパティの継承修飾子です。既定値は (None) です。new, virtual, override, virtual から選択できます。
Child Property - Name 親クラスで定義された子 Entity クラスを現すプロパティのプロパティ名です。
Parent Property - Access 子クラスで定義された親 Entity クラスを現すプロパティのアクセス修飾子です。既定値は public で、public, Internal を選択できます。
Parent Property - Inheritance Modifier 子クラスの親 Entity クラスを現すプロパティの継承修飾子です。既定は(None)で、(None), new, virtual, override, virtual を選択できます。
Parent Property - Name 子クラスの親 Entity クラスを現すプロパティのプロパティ名です。
Participating Properties 関連する Entity 間のプロパティを表示します。プロパティウィンドウで Participanting Properties にフォーカスがあるときに表示される右のボタンを選択すると関連を編集できます。
Unique AssociationAttribute の IsUnique に対応するプロパティです。 Cardinality が OneToOne の場合は、True である必要があります。既定値は False です。

 Inheritance (継承) デザイナプロパティ(デザイナ上で継承を選択します。)

Inheritance Default ディスクリクリミネータ値に該当する値がなかった場合に作成される規定の Entity クラスを設定します。InheritanceMappingAttribute の IsDefault プロパティを true に設定することに対応します。
Base Class Discriminator Value

基本クラスを作成するように判定するためにディスクリミネータ プロパティの値を定義します。

Derived Class Discriminator Value 継承クラスを作成するように判定するためにディスクリミネータ プロパティの値を定義します。 InheritanceMapingAttribute の Code に値を設定することに対応します。
Discriminator Property 単一テーブル継承による継承エンティティを特定するために使用するディスクリミネータとなる Entity クラスのプロパティを設定します。指定したプロパティの値によって 作成される Entity クラスが判定されます。ColumnAttribute の IsDiscriminator を true に設定することに対応します。

2.4 Delete, Insert, Update のマッピング

DataContext 継承クラスにインポートされたストアドプロシージャは エンティティクラスの Delete, Insert, Update 時に使用できるようにマッピングを行うことができます。デザイナ上で Entity クラスを選択して右クリックで表示される Configure Behavior を選択するか、 Entity クラス選択後に、Properties ウィンドウの DefaultMethod カテゴリに表示される、Delete, Insert, Update を編集することで実現できます。下図が マッピングを定義するときに使用される Configure Behavior ダイアログです。

 

今回は説明は以上です。指摘点、誤りなどがありましたら、ご連絡ください。

ASP.NET の LINQ to DataSource については触れていませんが、今回の内容と LINQ to SQL の備忘録1, 備忘録2, 備忘録3の内容を理解できれば LINQ to DataSource を使用するウィザードでも同じように編集することができるようになると思います。