使用单独的域和持久层处理聚合内部的变化
Handling Changes Inside Aggregate with Separate Domain and Persistance Layer
我是 DDD 的新手,但我正在尝试尽可能快地补习。我按照 https://github.com/dotnet-architecture/eShopOnContainers 作为如何使用 Mediatr 和 EF Core 构建我的代码的指南。
幸运的是,对于此应用程序,持久性和域模型是相同的。不幸的是,我的数据层与我们的领域模型不匹配,因为它是一个遗留数据库。
所以我将域与持久性分开,这很好。但是我很难理解如果我在命令处理程序中执行此代码块的位置(试图使其简单明了)...
var aggregate = repo.GetById(1234);
aggregate.AddItemToList(item);
repo.SaveChanges();
我怎样才能使回购协议的底层数据库上下文知道所应用的更改。我唯一能想到的就是进行 repo.Update(aggregate) 调用,然后尝试应用数据库调用来更新数据库的各个位置。
我觉得有点味道。
任何见解都会很棒。
谢谢!
编辑:
存储库模式应该具有单独的域和持久层 return 持久层的模型还是域的模型?
例如:
我有一家聚合公司。我有一个名为 CompanyLegacy 的数据库 table,它使用 entity framework 核心在持久层中建模。
我的存储库应该是 CompanyLegacyRepository 还是 CompanyRepository?如果是 CompanyRepository,那将意味着我查询 CompanyLegacy table,并将其映射到公司域模型,然后 return 它。此模型不会进行更改跟踪。这就是我的问题的来源。
但是,如果我应该执行 CompanyLegacyRepository,那么它似乎不符合 DDD 准则,其中所有操作都应用于 aggregateroot。
Should the repository pattern with a separate Domain and Persistence
layer return the persistence layer's model or the domain's?
存储库应该 return 您的域模型。如果您在基础架构层中使用 DTO(例如 CompanyLegacy),则您的存储库有责任将它们映射到您的域模型。请注意,在与您密切相关的Layered Architecture, the Application layer is not supposed to know about the DTOs used in the Infrastructure layer... it's your Domain models which are the heart of your application. See this question中。
您的存储库应称为 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);
}
更改跟踪
Entity Framework 更改跟踪有其局限性,这个问题是其中一个示例 Disconnected Scenarios,我们不能依赖 EF 更改跟踪(因为 DTO)。上述存储库的实现如下:
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.Add(companyLegacy);
_context.SaveChanges();
}
public void Update(Company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.Update(companyLegacy);
_context.SaveChanges();
}
}
This tutorial is helpful for more advanced operations and you can find more info about EF Core change tracking here.
this answer 与 EF 4/5/6(非核心)相关,但让您了解如何使用唯一标识符来决定是否应添加或更新实体。
我是 DDD 的新手,但我正在尝试尽可能快地补习。我按照 https://github.com/dotnet-architecture/eShopOnContainers 作为如何使用 Mediatr 和 EF Core 构建我的代码的指南。
幸运的是,对于此应用程序,持久性和域模型是相同的。不幸的是,我的数据层与我们的领域模型不匹配,因为它是一个遗留数据库。
所以我将域与持久性分开,这很好。但是我很难理解如果我在命令处理程序中执行此代码块的位置(试图使其简单明了)...
var aggregate = repo.GetById(1234);
aggregate.AddItemToList(item);
repo.SaveChanges();
我怎样才能使回购协议的底层数据库上下文知道所应用的更改。我唯一能想到的就是进行 repo.Update(aggregate) 调用,然后尝试应用数据库调用来更新数据库的各个位置。
我觉得有点味道。
任何见解都会很棒。
谢谢!
编辑: 存储库模式应该具有单独的域和持久层 return 持久层的模型还是域的模型?
例如: 我有一家聚合公司。我有一个名为 CompanyLegacy 的数据库 table,它使用 entity framework 核心在持久层中建模。
我的存储库应该是 CompanyLegacyRepository 还是 CompanyRepository?如果是 CompanyRepository,那将意味着我查询 CompanyLegacy table,并将其映射到公司域模型,然后 return 它。此模型不会进行更改跟踪。这就是我的问题的来源。
但是,如果我应该执行 CompanyLegacyRepository,那么它似乎不符合 DDD 准则,其中所有操作都应用于 aggregateroot。
Should the repository pattern with a separate Domain and Persistence layer return the persistence layer's model or the domain's?
存储库应该 return 您的域模型。如果您在基础架构层中使用 DTO(例如 CompanyLegacy),则您的存储库有责任将它们映射到您的域模型。请注意,在与您密切相关的Layered Architecture, the Application layer is not supposed to know about the DTOs used in the Infrastructure layer... it's your Domain models which are the heart of your application. See this question中。
您的存储库应称为 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);
}
更改跟踪
Entity Framework 更改跟踪有其局限性,这个问题是其中一个示例 Disconnected Scenarios,我们不能依赖 EF 更改跟踪(因为 DTO)。上述存储库的实现如下:
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.Add(companyLegacy);
_context.SaveChanges();
}
public void Update(Company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.Update(companyLegacy);
_context.SaveChanges();
}
}
This tutorial is helpful for more advanced operations and you can find more info about EF Core change tracking here.
this answer 与 EF 4/5/6(非核心)相关,但让您了解如何使用唯一标识符来决定是否应添加或更新实体。