データ永続性の管理
このセクションでは、Lino が Entity Framework Core をどのように構成してドメイン層を完全に分離し、データベースのマイグレーションプロセスを予測可能かつ管理可能にするかを学びます — 伝統的なモノリシックサービスでも、モジュラーサービスでも同様です。
lino new service コマンドでサービスを作成すると、CLIは2つの重要な選択を求めます:
- アーキテクチャ — 伝統的なサービスまたはモジュラーサービス。
- データプロバイダー —
SqlServer
またはPostgreSql
(将来的には他のプロバイダーも追加予定です)。
伝統的(モノリシック)サービスでもモジュラー(モノリシックモジュラー)サービスでも、サービスごとに単一のデータベースが使用されます。ただし、モジュラーサービスでは各モジュールが同一データベース内の別々のスキーマにマッピングされます。 これにより、各bounded contextが独立した論理的名前空間を保持し、機能的分離、独立したバージョニング、より整理された安全なマイグレーションが保証されます。
エンティティタイプ構成
LinoはPersistence‑Ignorantの原則に従っています:ドメインエンティティはインフラの詳細を知りません。
そのため、すべてのORMマッピングはIEntityTypeConfiguration<T>
を実装するクラスに移され、Configurations/<EntityName>Configuration.cs
に配置されています。
- 各エンティティは専用の構成ファイルを持っています。
- グローバルな規約(例:
decimal(18,2)
、照合順序、DateTime
をutc
として扱う)はModelConfiguration
に集中管理できます。 - 構成は
DbContext
のOnModelCreating
内でmodelBuilder.ApplyConfigurationsFromAssembly(...)
を使って適用されます。
DbContexts
DbContext
はアプリケーションのトランザクション単位を表します。Linoは自動的に生成します:
- 従来型サービス — すべての
DbSet<TEntity>
を含む単一のAppDbContext
。 - モジュール型サービス — 各bounded contextごとに
<Module>DbContext
を用意します。これにより、各モジュールのコンパイル速度が速くなり、マイグレーションサイクルが短縮され、マージコンフリクトのリスクが減少します。
すべてのDbContext
は<Module>/Infrastructure.Persistence
に登録され、IUnitOfWork
を通じて公開され、dependency injection
で解決されます。
リポジトリ
具体的なリポジトリは <Module>/Infrastructure.Persistence.Repositories
にあり、<Module>/Domain.Repositories
名前空間で定義されたインターフェースを実装します。
各リポジトリは以下の役割を持ちます:
- 複雑なクエリ(LINQ、
FromSql
、DTOプロジェクション)をカプセル化します。 - ドメインに必要なメソッドのみを公開します(アグリゲートルート中心)。
ユニット・オブ・ワーク (Unit of Work)
ユニット・オブ・ワーク は複数のリポジトリを調整する トランザクションの境界 として機能し、すべての操作が アトミック に実行されることを保証します。
単純なシナリオでは、DbContext
自体で十分な場合が多いですが、Lino はより高度な制御と柔軟性を提供する専用の実装(UnitOfWork
)を生成します。
- 必要に応じて、
BeginTransaction
、Commit
、Rollback
による手動トランザクション制御を可能にします。 - 現在のトランザクション内でドメインイベントを公開し、同じ
commit
サイクル内で実行されることを保証します。 - アウトボックスに統合イベントを永続化し、トランザクションアウトボックスパターンに従って分散アーキテクチャのシナリオで信頼性の高い配信を保証します(適用可能な場合)。
マイグレーションの管理
LinoはEntity Framework Coreを用いてデータベースマイグレーションのプロセスを完全に簡素化・自動化し、繰り返しの作業や一般的な不整合のリスクを排除します。 新しいマイグレーションを作成するには、次のコマンドを実行してください:
lino database migrations add
コマンドを実行すると、対話型ウィザードが次の情報を求めます:
- サービス — マイグレーションが適用されるプロジェクト名。
- モジュール — (モジュール型サービスの場合のみ)変更が属するモジュール。
-
マイグレーション名 — 変更内容の説明を入力してください(例:
AddCustomerIsActive
)。 Linoは現在のバージョンとインクリメント順序を自動的に管理し、.sql
スクリプトを次のパターンで生成します:/Scripts/v1.2.3/001_AddCustomerIsActive.sql
。
.cs
ファイルに加えて、LinoはDDLコマンドを含む対応する.sql
スクリプトも自動生成します。
これにより、手動での変更適用やインフラチームやDBAによるレビューが容易になります。