ADO.NET Entity Framework
Deep Dive
Atsushi Fukui (@afukui)
2013.08.03
Hokuriku.NET Vol.12 in Fukui
Agenda
自己紹介
Entity Framework とは
DbContext, DbSet<T>, DbQuery<T>
Code First, DB First, Model First
クエリ - LINQ to Entities
関連エンティティの読み込み
エンティティの更新
デタッチ オブジェクト
トランザクション
同時実行制御
ビュー、ストアドプロシージャの利用
自己紹介
福井 厚 (ふくい あつし)
@afukui
株式会社 アークウェイ
プリンシパル コンサルタント
現在、やる気と正義感のある若手社員を絶賛募集中
Microsoft Certified Architect – Solution Certification
(2008-)
Microsoft MVP – Windows Azure (2005-)
Visual Studio User Group 運営委員(2005-)
日本XPユーザーグループ スタッフ(2000-)
Entity Framework とは
Microsoft の開発した O/R マッパー
概念モデルとストレージモデルのマッピング
ADO.NET を利用
プロバイダ モデル
LINQ to Entities
DbContext, DbSet<T>, DbQuery<T>
DbContext
データベースの接続、トランザクションの管理
エンテ ィティの変更追跡
DbSet<T>
エンティティの集合、エンティティの追加、削除のメソッドを提供
DbQuery<T>
クエリ式
IOrderedQueryable<TResult>, IQueryable<TResult>,
IEnumerable<TResult>, IOrderedQueryable, IQueryable,
IEnumerable, IListSource を継承
AsNoTracking(), Include()
Code First, DB First, Model First
Code First
POCO クラスのエンティティ
DbContext 継承クラス
データベース、テーブルを自動生成
Enable-Migration
DB First
Entity Model Wizard
DbContext 継承クラス、エンティティ クラスのソースコードをT4テンプ
レートから生成
Model First
EDM から DDL を生成
Demo
Code First Demo //1
Database First Demo
データソースからメモリへの読み込み
using (var context = new NorthwindEntities())
{
//Local プロパティは Context に読み込まれたエンティティを表す
Console.WriteLine(context.Orders.Local.Count);
//Load メソッドで読み込み
var query = context.Orders.Load();
Console.WriteLine(context.Orders.Local.Count);
}
クエリ - LINQ to Entities
using (var context = new NorthwindEntities())
{
var q = from c in context.Customers
where c.Name.StartsWith("A")
orderby c.Name
select c;
foreach (var customer in q)
{
Console.WriteLine(customer.Name);
}
}
Extension Methods (Single, First, Take, Skip,
Sum …)
System.Linq.Querable クラスの拡張メソッド
SQL の確認
SQL Server Profiler
LINQPad
DbQuery<T>.ToString();
using (var context = new ShopEntities())
{
var query = from c in context.Customers
select c;
Console.WriteLine(query.ToString());
}
Demo
LINQ to Entity //2, 3
関連エンティティ
関連エンティティをロードする方法
Navigation Property
public partial class Customer
{
public Customer()
{
this.Orders = new HashSet<Order>();
}
public string CustomerID { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
関連エンティティの明示的な読み込み
Include
var q = from c in context.Customers
.Include(c => Orders)
select c;
関連エンティティを後から読み込み
context.Configuration.LazyLoadingEnabled = false;
var customer = (from c in context.Customers
select c).First();
if (!(context.Entry(customer).Collection(c =>
c.Orders).IsLoaded))
{
context.Entry(customer).Collection(
c => c.Orders).Load();
}
遅延ロード
context.Configuration.LazyLoadingEnabled = true;
Demo
関連エンティティのロード //5,6
Add(), Remove()
DbSet<T>.Add メソッド
TEntity のコレクションに TEntity を追加
追加したエンティティのステータスは EntityState.Added に変更される
context.Entry(customer).State で確認
DbSet<T>.Remove メソッド
対象のエンティティのステータスを EntityState.Deleted に変更される
using (var context = new NorthwindEntities())
{
var targetProduct = (from p in Products).First();
context.Products.Remove(targetProduct);
context.SaveChanges();
}
context.ChangeTracker.DetectChanges()
//自動変更検知を無効化
context.Configuration.AutoDetectChangesEnabled = false;
var customer = context.Customers.First();
customer.Name = "afukui";
Console.WriteLine("Customer State {0} ",
context.Entry(customer).State);
context.ChangeTracker.DetectChanges();
Console.WriteLine("Customer State {0} ",
context.Entry(customer).State);
エンティティのアタッチ
public void SaveCustomer(Customer customer)
{
using (ver context = new NorthwindEntities())
{
context.Customers.Attach(customer);
context.Entry(customer).State = EntityState.Modified;
context.SaveChanges();
}
}
Demo
その他いろいろ //7,8,9,10
トランザクション
SaveChanges メソッド内でローカル トランザクションを自動的に
実行
同時実行制御
同時実行モードを Fixed に変更
データソースが SQL Server の場合はタイム
スタンプ列を利用する方法が一番簡単
ビュー、ストアドプロシージャの利用
ビューはテーブル同様にモデルにマップ可能
プライマリキーとなるユニークな列が必要
ストアド プロシージャは DbContext 派生クラスの関数としてマッ
プされる
Q&A
ご質問をどうぞ
ご清聴ありがとうございました
© Copyright 2026 ExpyDoc