在我的解决方案中,EntityFramework 上下文在没有使用存储库模式的 UnitOfWork 的情况下被抽象的原因有很多,例如:
- 数据库优先方法(edmx 和自动生成的实体)
- 纯 ADO 和 EF 实现
- 域和数据库模式分离
所以我想出了一个问题,我需要添加两个相关实体,但不幸的是 DB 模式没有为该关系提供外键。假设它是Customer
和Address
关系。因此,这使我无法使用正常的 EF 功能将这些实体“一次性”存储在 db 中。这意味着我需要先存储,Customer
然后我需要从第一次插入开始存储。Address
CustomerID
我遇到的问题是,当我将域模型传递到 UnitOfWork 存储库时
UnitOfWork.CustomersRepository.Add(customerModel);
UnitOfWork.SaveChanges();
我无法将CustomerID
其传递给下一个数据库请求。我真的不想通过在存储库方法中调用.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)。也许这个问题还有更多的解决方案?