EF Core?
EF Coreは [Entity Framework]を軽量化したバージョンで、.NET Core 及び.NET 5 以上で使用できる。 データベースとの相互作用を単純化し、開発者がデータベースに対するクエリおよび操作を行うことができるORM(Object-Relational Mapping)ツールである。
主な機能
- データベースに対するCRUD(Create、Read、Update、Delete)作業を支援する。
- LINQ(Language Integrated Query)を使ってデータベースクエリを作成することができる。
- データベーススキーマをコードで定義できるCode Firstアプローチを提供する。
- 多様なデータベースシステムと互換性がある。
EF Coreのメリット
- 開発者がデータベースとの相互作用を容易にすることができる。
- データベースに対する抽象化階層を提供し、メンテナンスと拡張性を向上できる。
- 多様なデータベースシステムとの互換性を提供する。
- LINQを使って簡単にデータベースクエリを作成することができる。
EF Coreの限界
- EF Core は、まだすべてのEntity Framework の機能をサポートしない。
- 一部の高度なデータベース機能に対するサポートが制限されているケースがある。
- 性能の側面で、一部の状況では原始SQLクエリを作成する方がより効率的である可能性がある。
EF Coreの使い方
- プロジェクトにEF Core NuGet パッケージを追加する。
- DbContextクラスを作成し、データベース接続情報を設定する。
- モデルクラスを作成し、データベース テーブルとマッピングする。
- LINQを使用してデータベースクエリを作成して実行する。
- 変更内容をデータベースに保存または更新する。
Entity Framework Coreを使ったデータベースのインストール
- SQL Serverのインストール
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
- テストのためのInMemoryインストール
dotnet add package Microsoft.EntityFrameworkCore.InMemory
DbContext サブクラス作成
public class CatalogContext : DbContext
{
public CatalogContext(DbContextOptions<CatalogContext> options) : base(options)
{
}
public DbSet<CatalogItem> CatalogItems { get; set; }
public DbSet<CatalogBrand> CatalogBrands { get; set; }
public DbSet<CatalogType> CatalogTypes { get; set; }
}
EF Coreの構成 (データベースのリンク情報設定)
- SQL Serverを使う場合
builder.Services.AddDbContext<CatalogContext>( options => options.UseSqlServer( builder.Configuration.GetConnectionString("DefaultConnection")));
- InMemoryを使う場合
builder.Services.AddDbContext<CatalogContext>(options => options.UseInMemoryDatabase());
データの取得
var brandItems = await _context.CatalogBrands
.Where(b => b.Enabled)
.OrderBy(b => b.Name)
.Select(b => new SelectListItem {
Value = b.Id, Text = b.Name })
.ToListAsync();
- 名前順整列、Enabled属性でフィルタリング、SelectListItem形式のCatalogBrandsを照会
- 即時実行するために
.ToListAsync()
で呼び出しすることが重要である。
データのセーブ
// データの追加 Create
var newBrand = new CatalogBrand() { Brand = "Acme" };
_context.Add(newBrand);
await _context.SaveChangesAsync();
// データの修正 read and update
var existingBrand = _context.CatalogBrands.Find(1);
existingBrand.Brand = "Updated Brand";
await _context.SaveChangesAsync();
// データの削除 read and delete (alternate Find syntax)
var brandToDelete = _context.Find<CatalogBrand>(2);
_context.CatalogBrands.Remove(brandToDelete);
await _context.SaveChangesAsync();
- EF Coreは、エンティティをインポートして保存するための同期/非同期メソッドをすべてサポートする。
- ウェブアプリケーションでデータアクセス作業を待っている間、ウェブサーバースレッドが遮断されないようにするために非同期メソッドにasync/awaitパターンを使用することをお勧めする。
関連データの取得
- EF Coreは、エンティティをインポートする際にデータベースに直接保存されているすべてのプロパティを一緒にインポートする。
- 関連エンティティリストのようなNavigation属性は
null
値で入力される場合がある。 - このプロセスは、EF Coreがデータを必要以上に持ち込まないようにするため、要求を迅速かつ効率的な方法で処理し、応答を返す必要があるWebアプリケーションでは非常に重要である。
- 直ちにロード
eager loading
を使用してエンティティとの関係を含めるには、次のようにクエリにInclude
メソッドを使用して属性を指定することができる。
// .Include を使うためにはusing Microsoft.EntityFrameworkCoreを追加すべき
var brandsWithItems = await _context.CatalogBrands
.Include(b => b.Items)
.ToListAsync();
- 様々な関係を含めることができ、,
ThenInclude
を使用して下位関係を含めることもできる。 - ピリオドで区切られた文字列を
.Include()
メソッドに伝達してNavigation属性を追加する方法もある。 .Include("Items.Products")
specification
はフィルタリング論理をカプセル化できるだけでなく、どのプロパティを読み込むかを含め、返却データの形態を指定できる。
// すべての表現式基盤
Include query = specification.Includes.Aggregate(query, (current, include)
=> current.Include(include));
// 文字列基盤
Include query = specification.IncludeStrings.Aggregate(query, (current, include)
=> current.Include(include));
- また別の方法としては明示的ロード
explict loading
がある。 既読のエンティティに追加データをインポートすることはできるが、DB往復回数を最小限に抑える必要があるウェブアプリケーションでは使用しない方が良い。 - 基本的に使用しないように設定されており、
Microsoft.EntityFrameworkCore.Proxies
をインストールする必要がある。
コメント
コメントを投稿