查询存储库层中的多个实体时要返回的类型

本文关键字:实体 类型 返回 存储 查询 | 更新日期: 2023-09-27 18:00:27

这个问题涉及到以下几层:

  • 服务层(使用IoC调用Repository)
  • 域模型(POCO/域实体,定义的存储库接口)
  • 存储库层(EF.edmx和已实现的存储库)

很多时候,它实际上是直接的:存储库层通过实体框架查询数据库,并向调用方(即服务层)返回IList<SomeDomainEntity>。返回的类型是在域模型中定义的类型。

我遇到的问题是,当我需要在POCO A、B和C之间进行查询,并从所有POCO中获取要返回的数据时。由于我不处理存储库中的任何逻辑,我需要将这些数据返回到服务层进行处理(直接或更可能通过调用域模型上的一些逻辑)。然而,我再也没有从存储库查询的结果中返回给调用者的单个类型了。

在我看到的示例中,匿名类型当然可以处理此问题,但由于我不是直接从存储库中返回的数据中处理该逻辑,并且需要返回该逻辑,因此我需要一个物理类型来返回。以下是我想到但不确定我喜欢的一些解决方案:

  1. 在域模型中创建一个新的域实体,它本质上是我查询的所有数据的组合,因此可以返回这个新的单一类型。创建构造类型以满足查询需求似乎是错误的
  2. 让服务层分别调用A、B、C实体上的各个存储库,然后处理每个返回对象的数据。这似乎是很多额外的工作
  3. 创建要返回的ViewModel。这在我看来也不合适。我在服务层和UI层之间大量利用ViewModel类,但从未见过它们被用来从存储库返回

我不能是唯一一个跨多个实体查询以获取需要添加到类型并返回给调用者的数据集合的人。解决我的问题的常见做法或标准方法是什么?

谢谢!

查询存储库层中的多个实体时要返回的类型

如果这些实体与相关,并且您在一个地方查询所有实体,那么您应该尝试在域模型中找到它们的聚合根,或者如果它还不存在,您应该引入一个新的根,就像您在第一个选项中所说的那样。这是没有错的,直到它有意义。它应该为一个领域概念建模,您可能有一个,因为您创建了存储库方法。

如果这些实体不相关(好吧,可能在某种程度上是相关的,但不是像上面那样紧密),并且您只想一次性获得它们,那么您应该在服务层中处理它,在那里您可以使用多个存储库并组成一个结果对象。

你可能听说过导航属性和渴望加载的概念,但我把它写在这里是因为它可能是你问题的另一个答案(我看不到你的域模型)

我不会同意你的第三个建议(在存储库中创建视图模型),因为它打破了分离。

不同的实体可以相互关联,其中一个实体是聚合根。服务习惯于这类查询。我通常这样做:

public class MyService
{
    IEnumerable<UserWithMessages> Find()
    {
        var messages = _messageRepository.FindAll();
        var userIds = _messages.Select(x => x.UserId).Distinct().ToArry();
        var users = _userRepository.Find(userIds);
        return users.Select(x => new UserWithMessages(x, messages.Where(x => x.UserId == x.Id));
    }
}

这只是两个可以利用数据库中索引的数据库查询。所以应该很快。

我建议您为此使用DTO(数据传输对象)。将服务层与视图分离是一种常见的做法,DTO只允许您共享视图所需的重要信息。

根据系统的大小,有各种方法来实现系统的这一部分。在小型系统中,您可以使用扩展方法在数据传输对象中映射POCO实体

我建议你看看"自动映射器"。我想这对你来说真的很有用

http://www.codeproject.com/Articles/61629/AutoMapper

http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/