SlideShare a Scribd company logo
1 of 83
Download to read offline
Entity Framework
コードファースト
2016年6月1日 中島 祐次郎
サンプルの環境について
 EntityFramework 6.1.3
 Visual Studio Community 2015 Update1
 Microsoft SQL Server 2014 Express
2
Entity Frameworkの歴史
3
 Entity Framework 1
 .NET Framework 3.5 SP1に付属
 Entity Framework 4
 セカンドバージョン
 .NET Framework 4.0 に付属
 Entity Framework 4.1
 2011年4月にリリース
 コードファーストのサポート
 設定に勝る規約
 軽量なContextクラスのサポート
 Entity Framework 4.2
 2011年11月にリリース
 バグフィックス
 セマンティックバージョニングの採用
 Entity Framework 4.3
 2012年2月にリリース
 マイグレーション対応
 DbContextクラスのバグフィックス
 Entity Framework 5
 2012年8月にリリース
 .NET Framework 4.5がターゲットバージョン
 Enumサポート
 Spatialデータをサポート
 パフォーマンスの向上
 LocalDBのサポート
 Entity Framework 6
 2013年10月にリリース
 非同期DB処理のサポート
 独自コンベンション
 Entity Framework 6.1
 2014年3月にリリース
 Entity Framework 6.1.3
 2015年3月にリリース
 Entity Framework 7
 現在開発中(2016年3月時点)
コードファーストの概要
 Entity Framework4.1以降の機能
 エンティティ・クラス(POCO)からデータベースを自動生成
 ※POCOは「Plain-Old CLR Object」の略で、特別なクラスやインターフェイスを
継承、実装していないクラスのこと。
 規約に基づくソース・コードとデータベースの関連付け
 ※設定に勝る規約(Convention over Configuration:CoC)
 ソース・コードへのアノテーションによる検証機能
 ソース・コードとデータベースの関連付けをカスタマイズするためのFluent
API
 本来は「Code Only」と呼ばれていました。
「Database First」「Model First」と歩調を合わせるためです。
現在はデータベースをリバースエンジニアリングできます。
4
設定に勝る規約
(Convention over Configuration:CoC)
 Ruby on Railsなどのフレームワークで採用されている
 XMLなどの設定ファイルに設定内容を記述するのではなく、規約に沿った
ソース・コードを記述する
 規約を多く作ることで設定を減らし、より効率的な開発をサポート
5
インストール方法
6
 インストールはパッケージマネージェーコンソールで行います。
※[ツール(T)]->[NuGet パッケージ マネージャー(N)]->[パッケージ マネージャー コンソール(O)]
 インストール
 Install-Package EntityFramework –IncludePrerelease
 アップデート
 Update-Package –IncludePrerelease
コンテキスト・クラス
 データベースへの接続
 データの入出力
 自己追跡エンティティ(変更履歴管理)
 同時実行制御
7
コンテキスト・クラスの作成
 DbContextというクラスを継承させて定義する
 DbSetという型で、アクセスしたいエンティティ・クラスの一覧に対応するプ
ロパティを定義する。
 例
 public class TestDB : DbContext
 {
 public DbSet<Item> Items { get; set; }
 }
 ※DBContextはSystem.Data.Entity名前空間です。
8
 接続文字列が定義されていない場合は、ローカルのSQL Server Express
インスタンスに名前空間を含むコンテキスト・クラスの完全修飾名でデータ
ベースが作成される
 namespace Sample1
 {
 public class TestDB : System.Data.Entity.DbContext
 {
 public System.Data.Entity.DbSet<Item> Shouhin { get; set; }
 }
 }
コンテキスト・クラス
9
コンテキスト・クラス
 App.configまたはWeb.configで定義するデータベースの接続文字列のうち、
コンテキスト・クラス名と同じ名前のものが使用される。
下記はExpressの接続文字列です。
 namespace Sample1
 {
 public class TestDB : System.Data.Entity.DbContext
 {
 public System.Data.Entity.DbSet<Item> Shouhin { get; set; }
 }
 }
 <add name=“TestDB” providerName=“System.Data.SqlClient” connectionString=“Data
Source=.¥¥SQLEXPRESS;Initial Catalog=Test;server=CT470224¥SQLEXPRESS;Integrated
Security=True;MultipleActiveResultSets=True”/>
10
コンテキスト・クラス
11
 LocalDBを利用する。
 namespace Sample1
 {
 public class TestDB : System.Data.Entity.DbContext
 {
 public System.Data.Entity.DbSet<Employee> Employee { get; set; }
 }
 }
 <add name="TestDB"
connectionString="Server=(LocalDb)¥MSSQLLocalDB;AttachDbFilename=|DataDirectory|¥TestFile.mdf;Init
ial Catalog=Test;Integrated Security=true " providerName="System.Data.SqlClient"/>
エンティティ・クラス
 エンティティ・クラスはPOCOである必要があります。POCOは「Plain-Old
CLR Object」の略で、特別なクラスやインターフェイスを継承、実装してい
ないクラスのことです。
 例
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 namespace Sample1
 {
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 }
12
エンティティ・クラス
 エンティティ・クラスの複数形がテーブル名称になる。
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 日本語は複数化されない。
 public class 商品
 {
 [System.ComponentModel.DataAnnotations.Key]
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
13
エンティティ・クラス
 Table属性で明示的に指定できる。
 [System.ComponentModel.DataAnnotations.Schema.Table("Shouhin")]
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 Table属性でスキーマを指定する。
 [System.ComponentModel.DataAnnotations.Schema.Table("Shouhin", Schema ="Test")]
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
14
フィールド
 デフォルトはエンティティ・クラスのプロパティがテーブルのフィールド名に
なる。
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
15
フィールド
 基本的な型マッピング
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 public bool Field1 { get; set; }
 public Int16 Field2 { get; set; }
 public Int32 Field3 { get; set; }
 public Int64 Field4 { get; set; }
 public Single Field5 { get; set; }
 public double Field6 { get; set; }
 public decimal Field7 { get; set; }
 public DateTime Field8 { get; set; }
 public TimeSpan Field9 { get; set; }
 public DateTimeOffset Field10 { get; set; }
 public Guid Field11 { get; set; }
 public byte Field12 { get; set; }
 public byte[] Field13 { get; set; }
 }
16
フィールド
 null許容型のマッピング
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 public bool? Field1 { get; set; }
 public Int16? Field2 { get; set; }
 public Int32? Field3 { get; set; }
 public Int64? Field4 { get; set; }
 public Single? Field5 { get; set; }
 public double? Field6 { get; set; }
 public decimal? Field7 { get; set; }
 public DateTime? Field8 { get; set; }
 publicTimeSpan? Field9 { get; set; }
 public DateTimeOffset? Field10 { get; set; }
 public Guid? Field11 { get; set; }
 public byte? Field12 { get; set; }
 public byte[] Field13 { get; set; }
 }
17
フィールド
18
 Enumのマッピング
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 public ItemType ItemType { get; set; }
 }
 public enum ItemType {
 Type1,
 Type2
 }
フィールド
 string型のマッピングについて
 string型はnull許容型にする事はできません。
 string型は仕様がnull(Nothing)を受け付けるので
 もともとnullを許容しているからです。
 デフォルトのマッピングは下記、図1のようになります。
 Null以外にする場合は[System.ComponentModel.DataAnnotations.Required]
 を指定します。
 public class Item
 {
 public string ItemId { get; set; }
 [System.ComponentModel.DataAnnotations.Required]
 public string ShouhinName { get; set; }
 }
図2
図1
19
フィールド
 Column属性でマップ先の列の名称と型を明示的に指定する
 public class Item
 {
 public string ItemId { get; set; }
 [Column(name:"ItemName",TypeName ="varchar")]
 public string ShouhinName { get; set; }
 }
 ※Column属性はSystem.ComponentModel.DataAnnotations.Schema名前空間です。
 MaxLength属性でサイズを指定する。
 public class Item
 {
 public string ItemId { get; set; }
 [Column(TypeName = "varchar")]
 [MaxLength(50)]
 public string ShouhinName1 { get; set; }
 [MaxLength(50)]
 public string ShouhinName2 { get; set; }
 }
 ※Column属性はSystem.ComponentModel.DataAnnotations名前空間です。
20
フィールド
 StringLength属性でサイズを指定する。
 public class Item
 {
 public string ItemId { get; set; }
 [Column(TypeName = "varchar")]
 [StringLength(50)]
 public string ShouhinName1 { get; set; }
 [StringLength(50)]
 public string ShouhinName2 { get; set; }
 }
 ※StringLength属性はSystem.ComponentModel.DataAnnotations名前空間です。
※decimal型の有効桁数と小数点以下を指定する場合はFluent APIを利用します。解説は別途行います
21
 デフォルトでは「ID」または「クラス名+ID」というプロパティが主キーとなる
(大文字小文字は無視)
 public class Item
 {
 public string ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 public class Item
 {
 public string Id { get; set; }
 public string ShouhinName { get; set; }
 }
主キー
22
主キー
 short(Int16)/int(Int32)/long(Int64)型は自動採番(IDENTITY)になる
 public class Item
 {
 public int ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 [DatabaseGenerated(DatabaseGeneratedOption.None)]で自動採番になら
ない
 public class Item
 {
 [DatabaseGenerated(DatabaseGeneratedOption.None)]
 public int ItemId { get; set; }
 public string ShouhinName { get; set; }
 }
 ※DatabaseGenerated属性はSystem.ComponentModel.DataAnnotations.Schema名前空間です。
Z
23
主キー
 Key属性で明示的に指定する
 public class Item
 {
 [Key]
 public string ShouhinKey { get; set; }
 public string ShouhinName { get; set; }
 }
 ※Key属性はSystem.ComponentModel.DataAnnotations名前空間です。
24
複合キー
 Key属性とColumn属性のOrderプロパティを併用します。
 public class Item
 {
 [Key]
 [Column(Order = 1)]
 public string ShouhinKey1 { get; set; }

 [Key]
 [Column(Order = 2)]
 public string ShouhinKey2 { get; set; }

 public string ShouhinName { get; set; }
 }
 ※Key属性はSystem.ComponentModel.DataAnnotations名前空間です。
 ※Column属性はSystem.ComponentModel.DataAnnotations.Schema名前空間です。
25
リレーションシップ
(ナビゲーション・プロパティ)
 他のエンティティを参照するプロパティはナビゲーション・プロパティとなる
(テーブル間のリレーションシップが作成される)
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public Item Field1 { get; set; }
 }
26
リレーションシップ
(ナビゲーション・プロパティ)
27
 デフォルトではナビゲーション・プロパティの読み込みは
行いません。
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public Item Field1 { get; set; }
 }
リレーションシップ
(ナビゲーション・プロパティ)
28
 ナビゲーション・プロパティがvirtualで修飾されている場合、リレーション先のエン
ティティは遅延ロードされる。
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public virtual Item Field1 { get; set; }
 }
 【重要】
遅延ローディング「Lazy-loding」は実際に必要になるまで読み込みません。ループ
内で遅延読み込み処理を行うとクエリ回数が増大することに注意する必要がある。
リレーションシップ
(ナビゲーション・プロパティ)
29
 「Eager-loding」(遅延ローディング「Lazy-loding」の反対)を行う。
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public Item Field1 { get; set; }
 }
 【重要】
Eager-lodingのクエリは1回ですが、クエリ結果が大きくなり、メモリ使用量やパフォーマ
ンスに問題が起きる場合がある。
多重度
30
 単純に他のエンティティクラスを参照すれば多重度が「1」になる
 ICollectionインターフェースで他のエンティティクラスを参照すると多重度
が「多」となる
 互いにICollectionインターフェースで定義すれば多対多になる(中間テー
ブルが自動で生成される)
多重度
31
 ICollectionインターフェースで他のエンティティクラスを参照すると多重度
が「多」となる
 public class Head
 {
 public string HeadId { get; set; }
 public ICollection<Body> Bodys { get; set; }
 }
 public class Body
 {
 public string BodyId { get; set; }
 }
【ポイント】
Headクラスに複数(ICollection型)のBodyクラスを保持するフィールドを定義してい
ますが、マップ先はBody(Bodies)となります。
多重度
32
 互いにICollectionインターフェースで定義すれば多対多になる(中間テー
ブルが自動で生成される)
 public class Body1
 {
 public string Body1Id { get; set; }
 public ICollection<Body2> Bodys2 { get; set; }
 }
 public class Body2
 {
 public string Body2Id { get; set; }
 public ICollection<Body1> Bodys1 { get; set; }
 }
外部キー
33
 リレーションシップが定義されている場合、以下の名前と同じ型を持つプ
ロパティは外部キーとみなされる
 1.ナビゲーション・プロパティ名 + リレーション先の主キープロパティ名
 2.リレーション先のクラス名 + リレーション先の主キープロパティ名
 3.リレーション先の主キープロパティ名
※複数候補がある場合は上から優先
外部キー
34
 ナビゲーション・プロパティ名 + リレーション先の主キープロパティ名
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }

 public string Field1ItemId { get; set; }
 public Item Field1 { get; set; }
 } ※リレーションシップが定義されている場合に限る
外部キー
35
 リレーション先のクラス名 + リレーション先の主キープロパティ名
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public string ItemItemId { get; set; }
 public Item Field1 { get; set; }
 } ※リレーションシップが定義されている場合に限る
外部キー
36
 リレーション先の主キープロパティ名
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public string ItemId { get; set; }
 public Item Field1 { get; set; }
 } ※リレーションシップが定義されている場合に限る
外部キー
37
 ForeignKey属性で命名規則に沿わないプロパティを外部キーに設
定
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 }
 public class Zaiko
 {
 public string ZaikoId { get; set; }
 public string Test1 { get; set; }

 [ForeignKey("Test1")]
 public Item Field1 { get; set; }
 }
 ※ForeignKey属性はSystem.ComponentModel.DataAnnotations.Schema名前空間です
確認すべき項目...
38
 リレーションシップが作成された後は「更新ルール」や「削除ルール」を必
ず確認しましょう。
複合型(ComplexType)
39
 複数のプロパティで構成されるデータ型
 主キーとナビゲーション・プロパティを持たないクラスは
複合型とみなされる
 モデルのプロパティ乱立を防ぐ
 参照元のテーブルのフィールドにマッピングされる
 個別のテーブルにはマッピングされない。テーブルのいくつかのフィール
ドにマッピングされる
 複合型を参照しているプロパティ名 + 複合型のプロパティ名になる
(Column属性で明示的に指定できる)
複合型(ComplexType)
40
 複合型を参照しているエンティティ・クラス
 public class Employee
 {
 public string EmployeeId { get; set; }
 public Address Jusho { get; set; }
 }
 複数のプロパティで構成されるデータ型
主キーとナビゲーション・プロパティを持たない
 public class Address
 {
 public string Prefectures { get; set; }
 public string City { get; set; }
 public string Othre { get; set; }
 }
参照元のテーブルのフィールドにマッピングされる。
個別のテーブルにはマッピングされない。
テーブルのいくつかのフィールドにマッピングされる
複合型を参照しているプロパティ名 + 複合型のプロパティ名になる
複合型(ComplexType)
41
 Column属性で名前を指定
 public class Employee
 {
 public string EmployeeId { get; set; }
 [Column("X")]
 public Address Jusho { get; set; }
 }
 public class Address
 {
 [Column("Field1")]
 public string Prefectures { get; set; }
 [Column("Field2")]
 public string City { get; set; }
 [Column("Field3")]
 public string Othre { get; set; }
 }
無効
マッピングしないプロパティ
42
 NotMapped属性でマッピングしないプロパティを作成
 public class Item
 {
 public string ItemId { get; set; }
 [NotMapped]
 public string ItemName { get; set; }
 }
 ※ NotMapped属性はSystem.ComponentModel.DataAnnotations.Schema名前空間です
データの取得
43
 基本的なデータの取得
データの取得、保存の操作はLINQ to Entitiesを利用
 using (var db = new TestDB())
 {
 var selectQuery = from item in db.Items
 where item.ItemId == "A001"
 select item;
 var return1 = selectQuery.Any();
 var return2 = selectQuery.Single();
 var return3 = selectQuery.ToList();
 }
SELECT
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Items] AS [Extent1]
WHERE N'A001' = [Extent1].[ItemId]
)) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
SELECT TOP (2)
[Extent1].[ItemId] AS [ItemId],
[Extent1].[ItemName] AS [ItemName],
[Extent1].[ItemType] AS [ItemType]
FROM [dbo].[Items] AS [Extent1]
WHERE N'A001' = [Extent1].[ItemId]
SELECT
[Extent1].[ItemId] AS [ItemId],
[Extent1].[ItemName] AS [ItemName],
[Extent1].[ItemType] AS [ItemType]
FROM [dbo].[Items] AS [Extent1]
WHERE N'A001' = [Extent1].[ItemId]
データの登録
44
 基本的なデータの登録
 using (var db = new TestDB())
 {
 var newItem = new Item()
 {
 ItemId = "A001",
 ItemName = "Test",
 ItemType = ItemType.Type1
 };

 db.Items.Add(newItem);

 db.SaveChanges();
 }
 【重要】
 SQLの実行はSaveChangesメソッド実行時に処理されます。
 トランザクション内では複数のSQLが1回で処理されます。
INSERT [dbo].[Items]([ItemId], [ItemName], [ItemType])
VALUES (@0, @1, @2)
①新しいオブジェクトを作成
※var newItem = db.Items.Create(); でもOK
②オブジェクトを追加
③データソースに保存、オブジェクト
コンテキストの変更をリセットする
データの更新
45
 基本的なデータの更新
 using (var db = new TestDB())
 {
 var selectQuery = from item in db.Items
 where item.ItemId == "A001"
 select item;

 var updateItem = selectQuery.Single();
 updateItem.ItemName = "TestName";
 updateItem.ItemType = ItemType.Type2;

 db.SaveChanges();
 }
SELECT TOP (2)
[Extent1].[ItemId] AS [ItemId],
[Extent1].[ItemName] AS [ItemName],
[Extent1].[ItemType] AS [ItemType]
FROM [dbo].[Items] AS [Extent1]
WHERE N'A001' = [Extent1].[ItemId]
UPDATE [dbo].[Items]
SET [ItemName] = @0, [ItemType] = @1
WHERE ([ItemId] = @2)
①データを取得
②更新内容を設定
③データソースに保存、オブジェクト
コンテキストの変更をリセットする
データの削除
46
 基本的なデータの削除
 using (var db = new TestDB())
 {
 var selectQuery = from item in db.Items
 where item.ItemId == "A001"
 select item;

 var updateItem = selectQuery.Single();

 db.Items.Remove(updateItem);

 db.SaveChanges();
 }
SELECT TOP (2)
[Extent1].[ItemId] AS [ItemId],
[Extent1].[ItemName] AS [ItemName],
[Extent1].[ItemType] AS [ItemType]
FROM [dbo].[Items] AS [Extent1]
WHERE N'A001' = [Extent1].[ItemId]
①データを取得
②オブジェクトを削除
DELETE [dbo].[Items]
WHERE ([ItemId] = @0)
③データソースに保存、オブジェクト
コンテキストの変更をリセットする
SQLを直接実行
47
 SQLを直接する方法を採用する前に検討すること
 Entity Frameworkは概念モデルに対してプログラミングを行うことが基本です。
LINQで処理できない場合や、複雑すぎる場合、パフォーマンスが厳しい場合に
SQLを直接実行するようにします。
 SelectはDatabase.SqlQueryメソッドを使用します。
 Insert、Update、DeleteはDatabase.ExecuteSqlCommandメソッドを使用し
ます。
SQLの実行
48
 Database.SqlQueryメソッド
 private class Test
 {
 public string ItemId { get; set; }
 public string Field2 { get; set; }
 public string Field3 { get; set; }
 }
 ...
 var items = db.Database.SqlQuery<Test>("select ItemId, ItemName, ItemName as Field3 from items");
 foreach (var item in items)
 {
 Console.WriteLine("{0}:{1}:{2}", item.ItemId, item.Field2, item.Field3);
 }
名前が一致していないので
null(Nothing)
マッピングするクラスを用意します。
SQLの実行
49
 Database.ExecuteSqlCommandメソッド
 Console.WriteLine((from d in db.Items where d.ItemId == "A001" select d.ItemName).Single());

 db.Database.ExecuteSqlCommand("update items set ItemName = 'A' where ItemId = 'A001' ");

 db.SaveChanges();

 Console.WriteLine((from d in db.Items where d.ItemId == "A001" select d.ItemName).Single());
パラメータを利用したSQLの実行
50
 引数に直接パラメータを渡す
 var items = db.Database.SqlQuery<Test>(
 "select ItemId, ItemName from items where ItemId = @p0 and ItemName like @p1" ,"A001","A");

 foreach (var item in items)
 {
 Console.WriteLine("{0}:{1}", item.ItemId, item.ItemName);
 }
 SqlQueryメソッドまたはExecuteSqlCommandメソッドの引数に値を渡すと@p0、@p1...のように自動的に作成さ
れます。
@p0 @p1
パラメータを利用したSQLの実行
51
 引数にSqlParameterを渡す
 var parameter1 = new SqlParameter("@ItmeId", "A001");
 var parameter2 = new SqlParameter("@ItemName", "A");

 var items = db.Database.SqlQuery<Test>(
 "select ItemId, ItemName from items where ItemId = @ItmeId and ItemName like @ItemName" ,
 parameter1,
 parameter2);

 foreach (var item in items)
 {
 Console.WriteLine("{0}:{1}", item.ItemId, item.ItemName);
 }
 ※ SqlParameterはSystem.Data.SqlClient名前空間です
ログの出力
52
 SaveChangeなどの処理内容をログとして出力できます。
 using (var db = new TestDB())
 {
 db.Database.Log = (value) =>
 {
 Console.WriteLine(value);
 };

 var newItem = new Item()
 {
 ItemId = "A001",
 ItemName = "Test1",
 ItemType = ItemType.Type1
 };
 db.Items.Add(newItem);

 db.SaveChanges();
 }
トランザクション
53
 トランザクションの種類
 1.暗黙のトランザクション
 SaveChangesやExecuteSqlCommandの呼び出しが行われると、トランザ
クションのスコープにない場合に、自動的にローカルトランザクションを
開始します。
SQLの処理が終わるとコミットを行います。
 2.BeginTransactionメソッドを利用
 明示的にトランザクションを作成する場合に利用します。
 Entity Framework6から推奨
 3.TransactionScopeクラスを利用
 Framework 2.0で追加された機能
 分散トランザクションで利用可能
(複数のデータベースへの処理、MS-DTCの昇格)
 Azure SQL DB でサポートされていない分散トランザクションになってし
まうことがある。
トランザクション
54
 暗黙のトランザクション
 var newItem = new Item() { ItemId = "A001", ItemName = "Test1" };
 db.Items.Add(newItem);

 var newItem2 = new Item() { ItemId = "A002", ItemName = "Test2"};
 db.Items.Add(newItem2);

 db.SaveChanges();
接続、トランザクション開始、コミット、切断までを行う。
Opened connection
Started transaction
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
Committed transaction
Closed connection
トランザクション
55
 BeginTransactionメソッドを利用
 var tran = db.Database.BeginTransaction();
 try
 {
 var newItem = new Item() { ItemId = "A001", ItemName = "1" };
 db.Items.Add(newItem);
 db.SaveChanges();


 var newItem2 = new Item() { ItemId = "A002", ItemName = "2" };
 db.Items.Add(newItem2);
 var newItem3 = new Item() { ItemId = "A003", ItemName = "3" };
 db.Items.Add(newItem3);
 db.SaveChanges();

 tran.Commit();
 }
 catch
 {
 tran.Rollback();
 MessageBox.Show("err");
 }
①データベースへの接続、トランザクションの開始
※接続が行われていない場合のみ接続の処理を行う。
Opened connection
Started transaction
②1回目の処理
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
③2回目の処理(2つのSQLが実行される)
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
④コミット
Committed transaction
トランザクション
56
 TransactionScopeクラスを利用
※System.Transaction.dllを参照
 var newItem = new Item() { ItemId = "A001", ItemName = "1" };
 db.Items.Add(newItem);
 var newItem2 = new Item() { ItemId = "A002", ItemName = "2" };
 db.Items.Add(newItem2);

 using (var tran = new System.Transactions.TransactionScope())
 {
 db.SaveChanges();

 tran.Complete();
 }
Opened connection
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
INSERT [dbo].[Items]([ItemId], [ItemName]) VALUES (@0, @1)
Closed connection
トランザクション開始
※ログには出力されません。
トランザクション終了(コミット)
※例外発生時はスコープの範囲外になった時点で、
自動的にロールバックされます(Completeしない場合、ロールバックされる。)
LINQと直接SQLを利用した時の注意点
57
 ExecuteSqlCommandとSaveChangesの順序に注意
 SQLの実行順序が変わる
 ログを確認すること
 var parameter1 = new SqlParameter("@ItmeId", "A001");
 var tran = db.Database.BeginTransaction();
 var query = from d in db.Items where d.ItemId == "A001" select d;
 var row = query.Single();
 row.ItemName = "A1";
 db.Database.ExecuteSqlCommand(
 "update dbo.items set ItemName = 'A2' where ItemId = @ItmeId ", parameter1);
 db.SaveChanges();
 tran.Commit();
Started transaction
Select...
update dbo.items
set ItemName = 'A2'
where ItemId = @ItmeId
UPDATE [dbo].[Items]
SET [ItemName] = @0 WHERE ([ItemId] = @1)
Committed transaction
ストアドプロシージャ
58
 複数の結果を返すストアドプロシージャ
 ALTER PROCEDURE SelectTest @Name nvarchar(max) AS
 SELECT ItemId
 ,ItemName
 FROM dbo.Items
 WHERE ItemName = @Name
 var parameter1 = new SqlParameter("Name", "A");
 var result = db.Database.SqlQuery<Test>("SelectTest @Name", parameter1);
 foreach (var value in result.ToList())
 {
 Console.WriteLine("ItemId:{0}/ItemName:{1}", value.ItemId, value.ItemName);
 }
引数と返す結果の列名は重複しないように名前を設定します。
マッピングするクラスを用意します。
ストアドプロシージャ
59
 更新処理を行うストアドプロシージャ
 ALTER PROCEDURE [dbo].[UpdateTest] @ItemId nvarchar(128) @ItemName nvarchar(max) AS
 BEGIN
 UPDATE dbo.Items
 SET ItemName = @ItemName
 WHERE ItemId = @ItemId
 END
 var tran = db.Database.BeginTransaction();
 var parameter1 = new SqlParameter("ItemId", "A001");
 var parameter2 = new SqlParameter("ItemName", "A01");
 db.Database.ExecuteSqlCommand("UpdateTest @ItemId, @ItemName", parameter1, parameter2);
 tran.Commit();
ストアドプロシージャ
60
 結果を返すストアドプロシージャ(取得方法不明)
 ALTER PROCEDURE [dbo].[UpdateTest] @ItemId nvarchar(128) ,
 @ItemName nvarchar(max)
 AS
 BEGIN
 UPDATE dbo.Items
 SET ItemName = @ItemName
 WHERE ItemId = @ItemId
 return 100;
 END
楽観的(オプティミスティック)排他制御
 Timestampというアノテーションにより、データベースのレコードのバージョ
ンを表すプロパティを表現できる。
 SQL Server上ではrowversion型
 SaveChangesメソッドを呼び出した際に、そのプロパティの値とデータベー
ス上の値の比較が行われる。もし異なっている場合には、
DbUpdateConcurrencyException例外(System.Data.Entity.Infrastructure
名前空間)が発生し、書き込みは行われない。
 【重要】
データがクエリされてからデータが更新されるまでデータにロックが保持さ
れません。
61
楽観的排他制御
62
 Entity Frameworkが楽観的排他制御が採用されている理由
 1.トランザクションが長くなるとロックされている時間が長くなり、パフォーマン
スの低下を招く
 2.Webはステートレスであり、メモリにロックの状態を保持できないため
楽観的排他制御
63
 public class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }

 [Timestamp]
 public Byte[] Timestamp { get; set; }
 }
 using (var db = new TestDB())
 {
 var tran = db.Database.BeginTransaction();
 var selectQuery = from item in db.Items where item.ItemId == "A" select item;
 var updateItem = selectQuery.Single();
 updateItem.ItemName = "A02";
 db.SaveChanges();
 tran.Commit();
 }
UPDATE [dbo].[Items]
SET [ItemName] = @0
WHERE (([ItemId] = @1) AND ([Timestamp] = @2))
SELECT [Timestamp]
FROM [dbo].[Items]
WHERE @@ROWCOUNT > 0 AND [ItemId] = @1
楽観的排他制御
64
 SQLを直接実行した場合は制御されない
悲観的(ペシミステック)排他制御
65
 Entity Frameworkは楽観的排他制御を採用しており、悲観的排他制御の
理想的な手法はありません。
対応方法としてはストプロなどでWITH (ROWLOCK UPDLOCK)を指定しま
す。
Entity Frameworkは概念モデルに対してプログラミングを行うのが基本で
すが、悲観的排他制御を行う場合は止むを得ないです。
排他制御の選択基準
66
 悲観的排他制御の選択
 1.トランザクションが短い
 2.頻繁に更新され、同時実行が多発する場合
 3.金額、在庫などの更新
 楽観的排他制御の選択
 1.更新頻度が低い
 2.同時実行が少ない
 3.マスターメンテナンスなどの更新
変更履歴管理
 DbContextクラスのEntryメソッドで取得できるDbEntityEntryオブジェクトか
ら、エンティティの変更情報を取得できる。
 Stateプロパティ
状態 意味
Detached エンティティは作成直後で、まだコレクションに追加されていない
Unchanged エンティティは変更されていない。SaveChangesメソッドで変更を
反映した後もこの状態になる
Added エンティティはコレクションに追加されたが、まだ変更は反映され
ていない
Deleted エンティティは削除された
Modified エンティティは変更された
67
変更履歴管理
68
 DbPropertyEntryオブジェクト
状態 意味
CurrentValue 変更前のプロパティの値
OriginalValue 変更後のプロパティの値
IsModified プロパティの値が変更されたかどうか
変更履歴管理
69
 var newItem = db.Items.Create();
 Console.WriteLine(db.Entry(newItem).State); //Detached
 newItem.ItemId = "A";
 newItem.ItemName = "A001";
 db.Items.Add(newItem);
 Console.WriteLine(db.Entry(newItem).State); //Added
 db.SaveChanges();
 var query = from d in db.Items where d.ItemId == "A" select d;
 var item = query.Single();
 Console.WriteLine(db.Entry(item).State); //Unchanged
 item.ItemName = "B001";
 Console.WriteLine(db.Entry(item).State); //Modified
 Console.WriteLine(db.Entry<Item>(item).Property(i => i.ItemName).IsModified); //True
 Console.WriteLine(db.Entry<Item>(item).Property(i => i.ItemName).OriginalValue); //A001
 Console.WriteLine(db.Entry<Item>(item).Property(i => i.ItemName).CurrentValue); //B001
 db.Items.Remove(item);
 Console.WriteLine(db.Entry(item).State); //Deleted
変更履歴管理
 大量の更新処理を行う場合はオーバーヘッドを避けるため明示的に変更
管理を無効化することが望ましい。
 Configuration.AutoDetectChangesEnabledプロパティで指定できる。
エンティティのStateプロパティや、プロパティのIsModifiedプロパティが正し
く動作しなくなる。
ただし、変更履歴管理を無効にしても、プロパティごとのCurrentValueプロ
パティとOriginalValueプロパティは異なる値を保持し続ける。
70
データベースの初期化
71
 データベースの初期化(自動生成)はDatabaseクラスのSetInitializerメソッ
ドの引数にIDatabaseInitializerインターフェースを実装したクラスを指定す
ることでカスタマイズできる。
 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestDB>());
 ※ Database、DropCreateDatabaseIfModelChangesはSystem.Data.Entity名前空間です
 【重要】
間違えればデータを一瞬で失うので取り扱いには注意が必要です。
クラス名 意味
CreateDatabaseIfNotExists データベースが存在しない場合のみ自動生成を行う
DropCreateDatabaseAlways 常にデータベースを再生成する
DropCreateDatabaseIfModelChanges データベースが存在しないかモデルが変更された場
合に、自動的にデータベースを削除して再生成する
MigrateDatabaseToLatestVersion Code First Migrations を使用してデータベースを最新
のバージョンに更新する
NullDatabaseInitializer 何も実行しません。
データベースの初期化
72
 データベースを作成する際に、初期データを投入することが可能です。
IDatabaseInitializerインターフェースを実装したクラスまたはあらかじめ準
備されているクラスを継承し、Seedメソッドでデータベースの初期データを
作成します。
 class TestDBCreateDatabaseIfNotExists : CreateDatabaseIfNotExists<TestDB>
 {
 protected override void Seed(TestDB context)
 {
 base.Seed(context);
 var newItem = context.Items.Create();
 newItem.ItemId = "A";
 newItem.ItemName = "A001";
 context.Items.Add(newItem);
 context.SaveChanges();
 }
 }
 ...
 Database.SetInitializer(new TestDBCreateDatabaseIfNotExists<TestDB>());
Fluent API
73
 Fluent APIはデフォルトの規約と異なるモデルを扱う為のAPIです。
 Fluent APIはモデル構築時に呼び出される、OnModelCreatingメソッド内
から利用する。
 OnModelCreatingメソッドはコンテキスト・オブジェクトのイベントです。
 OnModelCreatingメソッドの引数はエンティティ・クラスとデータベース定義
のマッピングを行うDbModelBuilderオブジェクトで、これを利用します。
 DbModelBuilderはSystem.Data.Entity名前空間です。
 DbModelBulderはFluent Interface(流れるようなインターフェース)であり、メソッ
ドを連ねて呼び出します。
Fluent API
74
 decimal型はデータベースのテーブルにはnumeric(18,2)にマッピングされ
ます。これをFluent APIを利用し変更します。
 public class TestDB : System.Data.Entity.DbContext
 {
 public System.Data.Entity.DbSet<Item> Items { get; set; }
 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
 modelBuilder.Entity<Item>().Property(item => item.Juryo).HasPrecision(10, 1);
 modelBuilder.Entity<Item>().Property(item => item.Yoseki).HasPrecision(20, 4);
 base.OnModelCreating(modelBuilder);
 }
 }
DBからDBContextとPOCOを自動生成
75
 Entity Data Model ウィザードを使用します。
 [プロジェクト]メニューの[新しい項目の追加]を選択します。
DBからDBContextとPOCOを自動生成
76
 [データベースからのCode First]を選択します。
DBからDBContextとPOCOを自動生成
77
 データベースを選択します。
DBからDBContextとPOCOを自動生成
78
 モデルに含めるデータベースオブジェクトを選択します。
DBからDBContextとPOCOを自動生成
79
 生成されたDBContextです。
 public partial class TestDB : DbContext
 {
 public TestDB() : base("name=TestDB")
 {
 }
 public virtual DbSet<Item> Items { get; set; }
 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
 modelBuilder.Entity<Item>().Property(e => e.Juryo).HasPrecision(10, 1);
 modelBuilder.Entity<Item>().Property(e => e.Yoseki).HasPrecision(20, 4);
 modelBuilder.Entity<Item>().Property(e => e.Timestamp).IsFixedLength();
 }
 }
DBからDBContextとPOCOを自動生成
80
 生成されたモデルクラスです。
 public partial class Item
 {
 public string ItemId { get; set; }
 public string ItemName { get; set; }
 public decimal Juryo { get; set; }
 public decimal Yoseki { get; set; }
 [Column(TypeName = "timestamp")]
 [MaxLength(8)]
 [Timestamp]
 public byte[] Timestamp { get; set; }
 }
マイグレーション
81
 マイグレーション方法
 ・Code-Based Migrations
 ・Automatic Migrations
 MigrateDatabaseToLatestVersionの利用
 型パラメータにTMigrationsConfigurationが必要
 マイグレーションの有効化
 パケージマネージャコンソールでEnable-Migrationsコマンドを実行します。
 Enable-Migrationsを実行するとプロジェクトにMigrationsフォルダが作成されま
す。
 MigrationsフォルダにはConfigurationクラスが追加されます。
 移行で利用する主なコマンド
 Add-Migration
 スキャフォールディング(足場作り)を行います。
 Update-Database
 データベースへの移行を行います。
マイグレーション
82
 Migrationsの有効化
※パッケージマネージャコンソールで行います。
[ツール(T)]->[NuGet パッケージ マネージャー(N)]->[パッケージ マネージャー コンソール(O)]
 PM> Enable-Migrations
 Checking if the context targets an existing database...
 Code First Migrations enabled for project Sample1.
 PM>
 スキャフォールディング(足場作り)
 PM> Add-Migration TestDB
 Scaffolding migration 'TestDB'.
 The Designer Code for this migration file includes a snapshot of your current Code First model.
This snapshot is used to calculate the changes to your model when you scaffold the next migration.
If you make additional changes to your model that you want to include in this migration, then you
can re-scaffold it by running 'Add-Migration TestDB' again.
 PM>
マイグレーション
83
 データベースへの移行
 PM> Update-Database
 Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
 Applying explicit migrations: [201605302350350_TestDB].
 Applying explicit migration: 201605302350350_TestDB.
 Running Seed method.
 PM>
‘-Verbose’ でSQLの表示

More Related Content

What's hot

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
やってはいけない空振りDelete
やってはいけない空振りDeleteやってはいけない空振りDelete
やってはいけない空振りDeleteYu Yamada
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyYasuharu Nakano
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!Tetsutaro Watanabe
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門大樹 小倉
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜Yoshiki Nakagawa
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf憲昭 村田
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム信之 岩永
 
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]DeNA
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例Naoya Kishimoto
 
Spring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugSpring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugMasatoshi Tada
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48Preferred Networks
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るGo Miyasaka
 
Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話dcubeio
 

What's hot (20)

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
やってはいけない空振りDelete
やってはいけない空振りDeleteやってはいけない空振りDelete
やってはいけない空振りDelete
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Unreal Studio+建築CADのワークフロー
Unreal Studio+建築CADのワークフローUnreal Studio+建築CADのワークフロー
Unreal Studio+建築CADのワークフロー
 
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
 
Spring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugSpring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjug
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
 
Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話
 

Similar to Entity Framework

C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~Fujio Kojima
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravelRisa Ohnishi
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~Fujio Kojima
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説JPCERT Coordination Center
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0Yuta Matsumura
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)Fujio Kojima
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングkunihikokaneko1
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
Implementation patterns
Implementation patternsImplementation patterns
Implementation patternsTatsuya Maki
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for JavaTakuya Tsuchida
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
BindableProperty 書くのクソダリーんだけど、 あいつなんやねん(仮)
BindableProperty書くのクソダリーんだけど、あいつなんやねん(仮)BindableProperty書くのクソダリーんだけど、あいつなんやねん(仮)
BindableProperty 書くのクソダリーんだけど、 あいつなんやねん(仮)Takashi Kawasaki
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うTatsumi Naganuma
 

Similar to Entity Framework (20)

C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravel
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
 
Dynamic Data
Dynamic DataDynamic Data
Dynamic Data
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説
 
20091207
2009120720091207
20091207
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
Implementation patterns
Implementation patternsImplementation patterns
Implementation patterns
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for Java
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
BindableProperty 書くのクソダリーんだけど、 あいつなんやねん(仮)
BindableProperty書くのクソダリーんだけど、あいつなんやねん(仮)BindableProperty書くのクソダリーんだけど、あいつなんやねん(仮)
BindableProperty 書くのクソダリーんだけど、 あいつなんやねん(仮)
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使う
 
C#6.0の新機能紹介
C#6.0の新機能紹介C#6.0の新機能紹介
C#6.0の新機能紹介
 
Lombok java
Lombok javaLombok java
Lombok java
 

Entity Framework