Appearance
EF Core
[Required]EF Core固有のAPI、relational mapping、change tracking、transaction semanticsはこのreferenceに閉じる。作業対象に該当するarchitecture、application、persistence、runtime規約を併用し、このreferenceではEF CoreとRDB固有の差分だけを扱う。
Boundary and Mapping
[Required]DbContext、DbSet<T>、IQueryable<T>、EntityEntry<T>などEF Core固有型をFeatures側へ漏らさない。[Required]table名、column名、key、index、relation、conversion、concurrency tokenはInfrastructureのIEntityTypeConfiguration<T>に定義し、domain modelをprovider属性へ依存させない。[Required]Value ObjectはValueConverterまたはInfrastructureの永続化modelとのmappingでRDBが保存できる型へ変換する。[Contextual]domain modelをEF Core entityとして直接materializeする場合は、constructor、backing field、owned typeなどのmappingをInfrastructureに閉じ、永続化都合のpublic setterを追加しない。[Contextual]schemaとdomain modelの形が大きく異なる場合はInfrastructureに永続化modelを置き、repository境界で相互変換する。[Required]repository portからIQueryable<T>を返さない。queryの組み立てと実行はInfrastructureに閉じ、use caseが必要とする結果を返す。
DbContext and Tracking
[Required]DbContextはunit of workとして短命に扱い、singletonにしない。同一transactionで行う処理は同一instanceを使う。[Required]queryとSaveChangesAsyncには受け取ったCancellationTokenを渡す。[Recommended]更新しないqueryはAsNoTrackingを使う。更新対象を同じDbContextで読み書きする場合はtrackingを利用してよい。[Required]lazy loadingを暗黙の初期値にしない。必要なrelationはIncludeまたはprojectionで明示し、意図しないN+1 queryを避ける。[Recommended]読み取り専用queryは必要なcolumnとshapeへprojectionし、aggregate全体を目的なくmaterializeしない。
Concurrency and Transaction
[Required]SaveChangesAsyncはuse caseのtransaction boundary内で呼び、repositoryごとに独立してcommitしない。[Contextual]1回のSaveChangesAsyncで必要な変更をatomicに保存できる場合は、明示的なtransactionを追加しない。[Contextual]複数回のSaveChangesAsync、raw SQL、または複数adapterのDB操作を同じtransactionへ束ねる場合は、persistence規約のuse case固有TransactionをEF Core transactionで実装する。[Required]optimistic concurrencyを使うaggregateにはrow versionなどのconcurrency tokenをmappingし、DbUpdateConcurrencyExceptionをInfrastructureで捕捉してuse caseが判断できるpersistence resultへ変換する。[Required]unique constraintやforeign key違反を業務結果として扱う場合は、provider固有例外をFeaturesへ漏らさず、識別可能なpersistence resultへ変換する。[Required]retryされ得るtransactionまたはexecution strategy内で、メール、通知、決済、外部APIなどの外部副作用を実行しない。[Contextual]DB更新と確実な外部副作用の連携が必要なら、同じtransactionでOutbox recordを保存し、冪等な別処理で配送する。
Migrations and SQL
[Required]migrationはschema変更のartifactとしてInfrastructure側で管理し、domainまたはFeaturesの責務にしない。[Required]production起動時にmigrationを自動適用するか、deployment stepで適用するかは運用要件として明示し、暗黙に選ばない。[Contextual]raw SQLを使う場合はparameter bindingを使い、入力値を文字列連結しない。戻り値とtransactionはrepository contractに従わせる。[Contextual]provider固有SQL、index、locking hintを採用する場合は、必要な整合性または性能上の根拠を設計資料に残す。