正式リリースと言うことで、ウォークスルーを見ながら書いてみました。
作り方はコンソールアプリケーションのプロジェクトを作り、次の二つの参照を追加します。
- System.ComponentModel.DataAnnotations
- EntityFramework
EntityFramworkのアセンブリは間違えずにVersion 4.1の物を選択してください。
次のようにコードを追加します。
基本的にはDbContextを継承して作るコンテキストオブジェクトとその設定を行うDatabaseクラスが実務的なコーディングでは重要になりそうなので、そのあたりを重点的に学習した方が良さそうです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.ComponentModel.DataAnnotations;
namespace EF1
{
//Logクラスの定義
public class Log
{
//主キーの属性
[Key]
public int LogId { get; set; }
public DateTime time { get; set; }
public string description { get; set; }
//こうしておくとリレーションが設定される
public virtual Machine Machine { get; set; }
}
//Machineクラスの定義
public class Machine
{
//主キーの属性
[Key]
public int MachineId { get; set; }
public string name { get; set; }
//こうしておくとリレーションが設定される。こちらの主キーがLogの外部キーに設定される。
public virtual ICollection Logs { get; set; }
}
//コンテキストオブジェクト
public class LogContext : DbContext
{
public DbSet Logs { get; set; }
public DbSet Machines { get; set; }
}
class Program
{
static void Main(string[] args) {
//コードでスキーマ変更が行われた場合に変更をDBに反映する。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
using (var context = new LogContext()) {
//必要ならばMachineの更新をする。
Machine Alis;
Machine Ellen;
var alis = context.Machines.LongCount(e => e.name == "Alis");
if (alis == 0) {
Alis = new Machine { name = "Alis" };
context.Machines.Add(Alis);
}
else {
Alis = context.Machines.Where(e => e.name == "Alis").First();
}
var ellen = context.Machines.LongCount(e => e.name == "Ellen");
if (ellen == 0) {
Ellen = new Machine { name = "Ellen" };
context.Machines.Add(Ellen);
}
else {
Ellen = context.Machines.Where(e => e.name == "Ellen").First();
}
int recordsAffected = context.SaveChanges();
Console.WriteLine("Saved {0} entities to the database.", recordsAffected);
//Linq式でクエリーもできる。
var allAlis = from p in context.Machines
where p.name == "Alis"
orderby p.name
select p;
foreach (var mac in allAlis) {
Console.WriteLine(" - {0}", mac.name);
}
//Logの追加
Console.WriteLine("** Create Log Data **");
int i = 0;
for (i = 0; i < 10; i++) {
if ((i % 2) == 0) {
context.Logs.Add(new Log { Machine = Alis,
time = DateTime.Now,
description = "Description : " + i.ToString() });
}
else {
context.Logs.Add(new Log { Machine = Ellen,
time = DateTime.Now,
description = "Description : " + i.ToString() });
}
}
context.SaveChanges();
//追加したLogの表示
foreach (var log in context.Logs) {
Console.WriteLine("{0:yyyy/MM/dd hh:mm:ss.fff} : {1}\t: {2}",
log.time, log.Machine.name, log.description);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
}
データはApp.ConfigでしてしなければデフォルトではSQL Serverの.\SQLEXPRESSインスタンスにEF内の命名規則に合わせたデータベース名(<プロジェクト名>.<DbContextを継承したクラスの名前>)でデータベースが作成され、その中にデータクラスのクラス名でテーブルが作成されます。(テーブル名はコード内で属性で指定できます。)
既存データベースを使いたかったり、規定の命名規則ではないデータベース名にしたい場合にはApp.ConfigにconnectionStringを書きます。
追記:
プロファイラで見ると結構やばいSQLをEFが吐いているような感じがします。データ件数やトランザクション増えたときに大丈夫かな。。。手動でSQL文チューニングする方法もなさそうな感じが。
コメント
OPC Diary » Blog Archive » Entity Framework 4.1のCode First
素敵なエントリーの登録ありがとうございます – .NET Clipsからのトラックバック
[…] まずは前回のプロジェクトにApp.Configを追加します。 […]
[…] Code Firstの紹介記事で書いたこのLinq式。 1234var allAlis = from p in context.Machines where p.name == "ALis" […]
Entity Framework 4.1 Code Firstで接続先をコードで指定する
普通の人は9分9厘Code Firstでの接続先データベースはApp/Web.Configで変更すれば問題ないと思います。 しかしながら残りの1厘ぐらいはどうしようもなく、コードで接続先を変更しなければい…