我加入DDD和EF Core时遇到了问题。
我正在使用DDD架构制作项目。作为数据访问级别,我使用从here获取的通用工作单元模式。
public interface IUnitOfWork
{
IRepository<TDomain> Repository<TDomain>() where TDomain : class;
}
public interface IRepository<TDomain>
{
TDomain Get(Expression<Func<TDomain, bool>> predicate);
}
实现这些接口我使用EF Core。
我有一些包含2个类的域模型
public class MainClass
{
public int Id { get; set; }
public List<RelatedItem> Items { get; set; }
}
public class RelatedItem
{
public int Id { get; set; }
public MainClass Parent { get; set; }
public DateTime Date { get; set; }
public string SomeProperty { get; set; }
}
在我的项目的现实生活中,MainClass
包含数百个RelatedItems
的集合。为了执行某些操作,每个请求只需要一个RelatedItem
和一些日期。可以通过搜索Items
属性来完成。
在工作单元中填充EF Core的性能我必须从DB中明确加载具有相关项的实体,因为业务登录层对UnitOfWork的存储库的实现一无所知。但是这个操作非常慢。
所以我决定创建注入costructor MainClassService
的{{1}}并且只返回一个unitOfWork
的方法,并且它工作正常。
RelatedItem
所以我遇到因为EF Core而无法直接使用属性public class MainClassService
{
IUnitOfWork unitOfWork;
public MainClassService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork ?? throw new ArgumentNullException();
}
public RelatedItem GetRelatedItemByDate(int mainClassId, DateTime date)
{
return unitOfWork.Repository<RelatedItem>().Get(c => c.Parent.Id == mainClassId && c.Date == date);
}
}
的情况,但我应该因为DDD架构而使用它们。
我的问题是:使用这样的结构是否可以?
答案 0 :(得分:0)
从您的问题看来,MainClass
是聚合根,RelatedItem
是嵌套实体。此设计决策应基于必须保护的业务规则/不变量。当Aggregate需要变异时,它必须从存储库中完全加载,也就是说,Aggregate root及其所有嵌套实体和值对象在执行mutating命令之前必须在内存中,无论它有多大。
此外,将基础结构服务注入Aggregates(或嵌套实体)并不是一个好习惯。如果您需要这样做,那么您必须再次考虑您的架构。
因此,根据我的编写,您可以看到只有当您尝试改变聚合时,问题才会显现出来。如果您只需要阅读或查找它,您可以创建一些使用基础架构组件查找数据的专用服务。您的MainClassService
似乎就是这种情况,您只需要阅读/查找一些RelatedItem
实体。
为了明确目的只是阅读,MainClassService
需要返回RelatedItem
实体的只读表示。
所以,你刚刚迈出CQRS的第一步,模型被分成两部分:READ模型和WRITE模型。