正式リリースと言うことで、ウォークスルーを見ながら書いてみました。
作り方はコンソールアプリケーションのプロジェクトを作り、次の二つの参照を追加します。
- 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 ICollectionLogs { 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厘ぐらいはどうしようもなく、コードで接続先を変更しなければい…