【发布时间】:2019-05-16 22:41:50
【问题描述】:
我开始深入研究领域驱动设计,但我在存储库方面遇到了一些问题,而且 EF Core 显式加载会自动填充我的导航属性。
我有一个存储库,用于加载我的聚合根及其子级。但是,一些聚合子项需要稍后加载(我需要根据日期范围加载这些实体)。
例子:
加载计划所有者
计算日期范围
加载计划所有者的计划
我正在尝试将我的数据访问层与核心层隔离,这就是我有一些问题的地方。
想象一下我的存储库中的这种方法:
public List<Schedule> GetSchedules(Guid scheduleOwnePk, DateRange dateRange)
{
var schedules = dbContext.Schedules.Where(x => x.PkScheduleOwner == scheduleOwnerPk && x.StartDate >= dateRange.Start && x.EndDate <= dateRange.End).ToList();
return schedules;
}
我可以通过两种方式从核心层调用这个方法:
//Take advantage of EF core ability to fill the navigational property automatically
scheduleOwnerRepository.GetSchedules(scheduleOwner.Pk, dateRange)
或
var schedules = scheduleOwnerRepository.GetSchedules(scheduleOwner.Pk, dateRange);
//At this moment EF core already loaded the navigational property, so I need to clear it to avoid duplicated results
scheduleOwner.Schedules.Clear();
//Schedules is implemented as an IEnumerable to protect it from being changed outside the aggregator root
scheduleOwner.AddSchedules(schedules);
第一种方法的问题在于它将 EF 核心泄漏到核心层,这意味着如果我离开 EF 核心,属性ScheduleOwner.Schedules 将不再被填充。
第二种方法抽象了 EF 核心,但需要一些额外的步骤来填充 ScheduleOwner.Schedules。由于 EF Core 会在调用存储库方法后自动加载导航属性,所以我必须在添加结果之前将其清除,否则我将插入重复的结果。
遇到这种情况,你们是怎么处理的?您是利用 EF 核心功能还是遵循更自然的方法调用存储库方法并使用其结果来填充某些属性?
感谢您的帮助。
【问题讨论】:
-
我已经有几年没有接触过 EF 了,但是 tt 模板用于为所有数据类生成部分类,因此您可以添加将在模型更新期间持续存在的方法。我曾经使用此功能创建对逻辑层类的隐式强制转换,这些类反映了数据层 (EF) 类。所以我的查询方法将返回没有延迟加载导航属性的逻辑层对象。不确定这是否有帮助。祝你好运!
标签: c# entity-framework domain-driven-design ddd-repositories