Entity Framework
関連エンティティの読み込み
サーチ…
備考
モデルが正しく関連している場合は、EntityFrameworkを使用して関連するデータを簡単に読み込むことができます。あなたは、 怠惰な読み込み 、 熱心な読み込み 、 明示的な読み込みという3つの選択肢があります。
例で使用されるモデル:
public class Company
{
public int Id { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
// Navigation properties
public virtual Person Founder { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int CountryId { get; set; }
public int CityId { get; set; }
public string Street { get; set; }
// Navigation properties
public virtual Company Company { get; set; }
public virtual Country Country { get; set; }
public virtual City City { get; set; }
}
レイジーローディング
レイジーローディングはデフォルトで有効になっています。レイジーローディングは、派生したプロキシクラスを作成し、仮想ナビゲーションプロビジョニングをオーバーライドすることによって実現されます。遅延ロードは、プロパティに初めてアクセスするときに発生します。
int companyId = ...;
Company company = context.Companies
.First(m => m.Id == companyId);
Person founder = company.Founder; // Founder is loaded
foreach (Address address in company.Addresses)
{
// Address details are loaded one by one.
}
特定のナビゲーションプロパティに対してLazyローディングをオフにするには、virtualキーワードをプロパティ宣言から削除します。
public Person Founder { get; set; } // "virtual" keyword has been removed
Lazyの読み込みを完全に無効にしたい場合は、 Contextコンストラクタなどの設定を変更する必要があります。
public class MyContext : DbContext
{
public MyContext(): base("Name=ConnectionString")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
注意:シリアル化を使用している場合は、遅延ロードをオフにしてください。シリアライザはすべてのプロパティにアクセスするため、データベースからすべてのプロパティをロードします。さらに、ナビゲーションプロパティ間でループを実行することもできます。
熱心な読み込み
熱心な読み込みでは、必要なすべてのエンティティを一度に読み込むことができます。 1つのデータベース呼び出しですべてのエンティティを処理することを希望する場合は、 Eagerの読み込みが必要です。また、複数のレベルを読み込むこともできます。
関連するエンティティをロードするには2つのオプションがあります。 強く型付けするか、 Includeメソッドの文字列オーバーロードを選択できます。
強く型付けされた
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include(m => m.Founder)
.Include(m => m.Addresses)
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include(m => m.Addresses.Select(a => a.Country));
.Include(m => m.Addresses.Select(a => a.City))
.Take(5).ToList();
このメソッドは、Entity Framework 4.1以降で使用できます。 using System.Data.Entity;
て参照があることを確認してくださいusing System.Data.Entity;
セット。
文字列のオーバーロード。
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include("Founder")
.Include("Addresses")
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include("Addresses.Country");
.Include("Addresses.City"))
.Take(5).ToList();
明示的な読み込み
Lazyローディングをオフにした後は、エントリのLoadメソッドを明示的に呼び出して、遅延してエンティティをロードできます。 参照は単一のナビゲーションプロパティをロードするために使用されますが、 Collectionはコレクションを取得するために使用されます。
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference(m => m.Founder).Load();
// Load addresses
context.Entry(company).Collection(m => m.Addresses).Load();
Eagerの読み込み時には、上記のメソッドのオーバーロードを使用してエンティティを名前で読み込むことができます:
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference("Founder").Load();
// Load addresses
context.Entry(company).Collection("Addresses").Load();
フィルタ関連のエンティティ。
Queryメソッドを使用して、ロードされた関連エンティティをフィルタリングできます。
Company company = context.Companies.FirstOrDefault();
// Load addresses which are in Baku
context.Entry(company)
.Collection(m => m.Addresses)
.Query()
.Where(a => a.City.Name == "Baku")
.Load();
投影のクエリ
関連するデータが非正規化型である必要がある場合、または列のサブセットのみが投影クエリを使用できる場合などです。余分な型を使用する理由がない場合、値を匿名型に結合する可能性があります。
var dbContext = new MyDbContext();
var denormalizedType = from company in dbContext.Company
where company.Name == "MyFavoriteCompany"
join founder in dbContext.Founder
on company.FounderId equals founder.Id
select new
{
CompanyName = company.Name,
CompanyId = company.Id,
FounderName = founder.Name,
FounderId = founder.Id
};
あるいは、クエリ構文で:
var dbContext = new MyDbContext();
var denormalizedType = dbContext.Company
.Join(dbContext.Founder,
c => c.FounderId,
f => f.Id ,
(c, f) => new
{
CompanyName = c.Name,
CompanyId = c.Id,
FounderName = f.Name,
FounderId = f.Id
})
.Select(cf => cf);