我对DDD相当陌生,但我正在尝试尽可能快地进行补习。我遵循https://github.com/dotnet-architecture/eShopOnContainers作为如何使用Mediatr和EF Core构建代码的指南。
幸运的是,对于此应用程序,持久性和域模型是相同的。对我来说不幸的是,我的数据层与我们的域模型不匹配,因为它是旧版数据库。
所以我将域与持久性分开,这很好。但是我很难理解如果我在命令处理程序中执行此代码块的位置(试图使其变得简单明了)...
var aggregate = repo.GetById(1234);
aggregate.AddItemToList(item);
repo.SaveChanges();
我如何使存储库的基础数据库上下文知道已应用的更改。我唯一能想到的就是有一个repo.Update(aggregate)调用,然后尝试应用数据库调用来更新数据库的各个位置。
这对我来说似乎是一种气味。
任何见解都会很棒。
谢谢!
编辑:具有单独的“域和持久性”层的存储库模式是否应该返回持久性层的模型还是域的模型?
例如:我有一家公司。我有一个名为CompanyLegacy的数据库表,该表使用实体框架核心在持久层中建模。
我的存储库应该是CompanyLegacyRepository还是CompanyRepository?如果是CompanyRepository,则意味着我查询CompanyLegacy表,并将其映射到Company域模型,然后将其返回。此模型将不会跟踪更改。这就是我的问题所在。
但是如果我应该做一个CompanyLegacyRepository,那么看来这不符合DDD准则,在DDD准则中,所有操作都将应用于聚合根。
应该将存储库模式与单独的域和持久性一起使用层返回持久层的模型还是域的模型?
存储库应返回您的域模型,如果您在持久层中使用DTO,则存储库有责任将它们映射到您的域模型。 more info here
您的存储库应称为CompanyRepository
。您可以为此存储库定义一个接口,例如:
public interface ICompanyRepository
{
// Company is your domain model not DTO (i.e. your legacy model)
Company GetById(int id);
void Add(Company);
void Update(Company);
}
这是实现存储库的方式:
public CompanyRepository: ICompanyRepository
{
Private MyDbContext _context;
public CompanyRepository(MyDbContext myDbContext) { _context = myDbContext; }
public Company GetById(int id)
{
var companyLegacy = _context
.CompanyLegacy
.AsNoTracking()
.Where(c => c.id = id)
.FirstOrDefault();
return MyMapper.ToCompany(companyLegacy);
}
public void Add(Company company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.CompanyLegacy.Add(companyLegacy);
_context.SaveChanges();
}
public void Update(Company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.Entry(companyLegacy).State = EntityState.Modified;
_context.SaveChanges();
}
}
有关EF Core Change Tracking和this answer的更多信息将帮助您确定是添加还是更新实体。