假设您有一个域对象:
class ArgumentEntity
{
public int Id { get; set; }
public List<AnotherEntity> AnotherEntities { get; set; }
}
你有 ASP.NET Web API 控制器来处理它:
[HttpPost("{id}")]
public IActionResult DoSomethingWithArgumentEntity(int id)
{
ArgumentEntity entity = this.Repository.GetById(id);
this.DomainService.DoDomething(entity);
...
}
它接收实体标识符,通过 id 加载实体并使用域服务在其上执行一些业务逻辑。
问题: 这里的问题是相关数据。ArgumentEntity具有AnotherEntities集合,仅当您通过 Include/Load 方法明确要求这样做时,EF 才会加载该集合。 DomainService是业务层的一部分,应该对持久性、相关数据和其他 EF 概念一无所知。
DoDomething服务方法期望接收带有加载的 AnotherEntities集合的ArgumentEntity实例。您会说 - 这很简单,只需在Repository.GetById中包含所需的数据并使用相关集合加载整个对象。
现在让我们从简化示例回到大型应用程序的现实:
ArgumentEntity要复杂得多。它包含多个相关集合,并且相关实体也有其相关数据。
您有多种DomainService方法。每种方法都需要加载相关数据的不同组合。
我可以想象可能的解决方案,但它们都远非理想:
总是加载整个实体 -> 但它效率低下而且通常是不可能的。
添加几个存储库方法:GetByIdOnlyHeader、GetByIdWithAnotherEntities、GetByIdFullData以在控制器中加载特定的数据子集 -> 但控制器会知道要加载哪些数据并将其传递给每个服务方法。
添加几个存储库方法:GetByIdOnlyHeader、GetByIdWithAnotherEntities、GetByIdFullData以在每个服务方法中加载特定的数据子集 -> 效率低下,每个服务方法调用的 sql 查询。如果您为一个控制器操作调用 10 个服务方法怎么办?
每个域方法调用存储库方法来加载额外的所需数据(例如:EnsureAnotherEntitiesLoaded)-> 这很难看,因为我的业务逻辑意识到相关数据的 EF 概念。
问题: 在将实体传递到业务层之前,您将如何解决加载实体所需的相关数据的问题?