在Repository层中查询多个实体时要返回什么类型?

我在这个问题中涉及以下层:

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

很多时候它非常直接:存储库层通过Entity Framework查询数据库并将IList返回给调用者,即调用者服务层。 返回的类型是域模型中定义的类型。

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

一个匿名类型的课程在我看到的例子中处理这个,但由于我不是直接在Repository中从返回的数据处理那个逻辑而需要返回它,我需要一个物理类型来返回。 以下是我想到的一些解决方案,但不确定我是否喜欢:

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

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

谢谢!

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

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

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

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

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

 public class MyService { IEnumerable 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)); } } 

只有两个DB查询可以使用DB中的索引。 所以它应该很快。

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

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

我建议你看看“AutoMapper”。 我认为这对你来说真的很有用

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

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