工作单位模式中的EF Core封装

时间:2018-05-15 20:22:20

标签: c# entity-framework domain-driven-design ef-core-2.0 ddd-repositories

我加入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架构而使用它们。

我的问题是:使用这样的结构是否可以?

1 个答案:

答案 0 :(得分:0)

从您的问题看来,MainClass是聚合根,RelatedItem是嵌套实体。此设计决策应基于必须保护的业务规则/不变量。当Aggregate需要变异时,它必须从存储库中完全加载,也就是说,Aggregate root及其所有嵌套实体和值对象在执行mutating命令之前必须在内存中,无论它有多大。

此外,将基础结构服务注入Aggregates(或嵌套实体)并不是一个好习惯。如果您需要这样做,那么您必须再次考虑您的架构。

因此,根据我的编写,您可以看到只有当您尝试改变聚合时,问题才会显现出来。如果您只需要阅读或查找它,您可以创建一些使用基础架构组件查找数据的专用服务。您的MainClassService似乎就是这种情况,您只需要阅读/查找一些RelatedItem实体。

为了明确目的只是阅读,MainClassService需要返回RelatedItem实体的只读表示。

所以,你刚刚迈出CQRS的第一步,模型被分成两部分:READ模型和WRITE模型。