私のソリューションでは、EntityFramework コンテキストが UnitOfWork with repositories パターンなしで抽象化されるのには、次のような複数の理由があります。
- DB ファーストのアプローチ (edmx および自動生成されたエンティティ)
- 純粋な ADO および EF の実装
- ドメインとデータベース スキーマの分離
そのため、2 つの関連するエンティティを追加する必要があるという問題が発生しましたが、残念ながら DB スキーマはその関係に外部キーを提供しません。Customer
とAddress
関係があるとしましょう。そのため、通常の EF 機能を使用して、これらのエンティティを「一度に」データベースに格納することができなくなります。つまりCustomer
、最初に保存する必要があり、次に最初の挿入から保存Address
する必要があります。CustomerID
私が抱えている問題は、ドメインモデルを UnitOfWork リポジトリに渡すときです
UnitOfWork.CustomersRepository.Add(customerModel);
UnitOfWork.SaveChanges();
CustomerID
それを次の db リクエストに渡すことができません。リポジトリ メソッド.SaveChanges()
で EF コンテキストに対して呼び出すことで、パターンを壊したくありません。.Add
調査の結果、このような場合、このプロセスをトランザクションにラップすることが最善であることがわかりました(これにより、efcontext.SaveChanges()
Repository メソッド内で使用する必要があります)が、UnitOfWork.SaveChanges()
実際にはトランザクション全体をコミットします。
しかし、SOの回答では見たことのない別のアプローチも見つけました。自動生成されたクラスのCustomerID
プロパティの変更についてドメインモデルに「通知」できる方法があるかどうかを調査しました。Customer
そして、それを支援するライブラリがあります: https://github.com/Fody/PropertyChanged
自動生成されたEF クラスは次のように定義されているため、次のpartial
ように記述できます。
public partial class Customer : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
そして.Add
メソッド:
public void Add(CustomerModel customerModel)
{
var newCustomer = new Customer
{
Name = customerModel.Name
};
_context.Customers.Add(newCustomer);
newCustomer.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == nameof(Customer.CustomerID))
{
customerModel.ID = newCustomer.CustomerID;
}
};
}
そのおかげで、自動生成されたコードを変更していません。UoW パターンを大幅に壊すこともなく、挿入された ID を外部に配信できます。
しかし、私の質問は、そのアプローチが受け入れられるかどうかわからないことと、どちらのアプローチを使用するか (トランザクションまたは Fody) がわからないということです。たぶん、その問題にはさらにいくつかの解決策がありますか?