CTP5
最終更新:
atachi
コードの実装と実行(サンプルプロジェクト)
データベースへの接続にはSQLServerCompact4を使っています。
このサンプルプロジェクトでは、Categoryテーブルにデータを追加するだけのサンプルです。 一回目の実行は正常に終了しますが、 二回目の実行は失敗 します。 これは、Categoryテーブルの主キーはユニークでなければならないため、一回目の実行で「FOOD」という値を持ったレコードが保存されているので、二回目の実行で「FOOD」という値を持ったレコードを作成できないためです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.Database;
namespace Ef4Ctp5
{
class Program
{
static void Main(string[] args)
{
DbDatabase.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
using (var db = new ProductContext())
{
// Add a food category
var food = new Category { CategoryId = "FOOD", Name = "Foods" };
db.Categories.Add(food);
int recordsAffected = db.SaveChanges();
Console.WriteLine(
"Saved {0} entities to the database, press any key to exit.",
recordsAffected);
Console.ReadKey();
}
}
}
public class ProductContext : DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
}
/// <summary>
/// エンティティ
/// </summary>
public class Category
{
public string CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
/// <summary>
/// エンティティ
/// </summary>
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
}
データベースの中身を確認
データベースにSQLCE4を使用している場合は、SQLCE4用のデータベースビューワーが別途必要です(VS2010のデータベースエクスプローラーはSQLCE3.5までしか対応していない)
下記のサイトからSQLCE4で作成したデータベースファイルを表示するソフトをダウンロードすることができます。
規約
多くの設定は規約により初期設定が定義されています。(規約についてはこちらのブログポストも参照)
- 主キーの規約
- 外部キーの規約
- 逆関連設定
- 複合型の使用
プログラマが任意にこれらの規約を再設定したい場合はアノテーションを使用します。
アノテーションを使用するには「System.ComponentModel.DataAnnotations」アセンブリをプロジェクトに参照してください
主キーの規約
ブログポストを引用しています。
Previously Code First would infer that a property is a primary key if the property is called ‘Id’ or ‘<class name>Id’. The only change to this convention is that once primary key properties are detected if their type is ‘int’, ‘long’ or ‘short’, they are registered as identity columns in the database by default. Primary key detection is not case sensitive.
この記述にもあるように、モデルクラスのプロパティで「Id」もしくは「クラス名+Id」という名前を主キーとします。
外部キーの規約
インスタンスとしての参照先のクラスに主キーとなるプロパティが存在する場合は、外部キーに相当するプロパティをクラス定義に記述することをしなくても自動的に外部キーを作成しマッピングします。
public class Person
{
[Key]
public virtual Int32 PersonId{get;set;}
public virtual string Name{get;set;}
}
public class Student
{
public virtual Int32 StudentId{get;set;}
// 外部キーによって結びつけられるインスタンス
public virtual Person Person{get;set;}
}
複合型の使用
主キーがない型がエンティティモデルに設定されている場合、それは外部キーによる参照制限ではなく複合型としてマッピングされます。
public class Person {
public int PersonId { get; set; }
// Nameクラスは主キーが定義されていないので
// このフィールドは関連としてではなく複合型でマッピングされる
public Name Name { get; set; }
}
// Keyアノテーションを使って主キーを定義していないクラス
public class Name {
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
スキーム変更の適応
下記のコードではエンティティモデルに変更があった場合に、データベースのスキームを変更します。
ただし、変更方法として、一度テーブルをDROP(削除)してからテーブルを作成する方法のため、
既存のデータはすべて失われます
。
DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<MyDataContext>());
データアノテーション
プログラマによってマッピングの設定を任意に行うことができます。
これは規約をオーバーライドすることができます。
いくつかのアノテーションは.NET Frameworks4に含まれているもので「System.ComponentModel.DataAnnotations.dll」に含まれています。
プロジェクト内でアノテーションを使用するには、このDLLも忘れずに参照設定へ加えます。
主キーの設定
Keyアノテーションを使って設定します。
コードファーストの規約では主キーはint型やlong型が選択されますが、Keyアノテーションを使うと任意のプロパティを主キーとしてマッピングできます。
public class Person{
[Key]
public string PersonId{get;set;}
}
フィールドへの制約を設定
- StringLength
- 文字列型に対して格納可能な文字数を制限します。
- MaxLength
- 文字列型に対して、格納可能な文字数の最大値を設定します。
- MinLength
- 文字列型に対して、格納可能な文字数の最小値を設定します。
- ConcurrencyCheck
- Required
- NULL値を許容しないか。
- Timestamp
- DataMember
- DatabaseGenerated
-
フィールドの値がデータベースによって作成されることを示します。
多くのデータベース設計では、主キーはAUTO INCREMENTを使ってデータベースが自動的に番号を振り分けます。
また、TIMESTAMP型のフィールドは自動的にレコードの更新日時を保存します。 - NotMapped
- データベースとのマッピングを行う必要のないプロパティです。
関連設定
2つのモデル間で外部キーと主キーが規約によって見つけることができる場合には、関連設定を記述する必要はありません。
次の例は主キー(SSN)と外部キー(AuthorSSN)が規約とは異なるため、RelatedToアノテーションで明示しています。
public class Book {
[Key]
public string ISBN { get; set; }
[StringLength(256)]
public string Title { get; set; }
public string AuthorSSN { get; set; }
[RelatedTo(RelatedProperty=“Books”, Key=”AuthorSSN”, RelatedKey=”SSN”)]
public Person Author { get; set; }
}
public class Person {
[Key]
public string SSN { get; set; }
[StringLength(512)]
public string Name { get; set; }
[RelatedTo(RelatedProperty=”Author”)]
public ICollection<Book> Books { get; set; }
}
動的なテーブル作成
FluentAPIを使ってプログラマブルにテーブルを定義することができます。
詳細は下記のサイトを参照してください。
データの取得
DbSetはIQuaryableをインターフェースとして持っています。
よって、LINQを使ってデータの検索を行うことができます。
// PersonIdをキーにして検索を行う。
string key = "1";
var person = (from p in MyCbContext.Persons
where p.PersonId == key
select p).Single();
LINQについてはこちらのページを参照してください。