存储库设计混乱

时间:2017-02-23 10:03:52

标签: c# design-patterns repository-pattern

我有以下存储库:

  • EmployeeRepository
  • DocumentRepository
  • CourseRepository
  • LeaveRepository

我们现在要求添加一个名为BusinessTripBidding的新业务对象,该对象允许员工为不同的商务旅行投标等等。无论如何,问题是当返回Bidders列表时,我需要在业务需要时包含来自上述所有存储库的信息,然后生成一个新对象并返回一个列表(在我的业务对象中),像这样:

IEnumerable<BidderInfo> GetBiddersInfo(int tripId)
{
    List<Bidder> bidders = _bidderRepository.GetListByTripId(tripId);

    List<Course> courses = _courseRepository
         .GetListByEmployeeId(bidders.Select(b => b.EmployeeId).AsEnumerable());

    List<Document> passports = _documentRepository
         .GetListByEmployeeId(bidders.Select(b => b.EmployeeId).AsEnumerable(), DocumentType.Passport);

    List<Leave> leaves = ...........

    var biddersInfo = new List<BidderInfo>();
    foreach(Bidder b in bidders)
    {
        var bi = new BidderInfo();
        bi.Courses = courses.Where(c => c.EmployeeId == b.EmployeeId).ToList();
        bi.Passport = passports.FirstOrDefault(p => p.EmployeeId == b.EmployeeId);

        bi.ComingLeave = .........

        // the same for the rest of the repositories

        biddersInfo.Add(bi);
    }
    return biddersInfo;
}

除了对db的多次调用之外,在循环旁边,如果我创建一个新的存储库,只负责在一个查询中创建这个BidderInfo,那么我们就会更容易调用它{ {1}}然后将此存储库注入业务对象的构造函数中。

现在,我应该保留我正在做的事情(多个数据库调用),但事情看起来正确; 或者我应该创建另一个存储库并将其传递给业务对象以使事情更快一些?在这种情况下,最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

最佳做法取决于数据的数量和变化速度。 如果您的数据只有几百/几千行且变化缓慢,您可以将其缓存在应用程序中,并在更新时使缓存无效。 当您的数据太大而无法将其存储在内存中时,我会尽可能避免多次调用而不会大幅增加代码复杂性。

答案 1 :(得分:1)

我会避免存储库之间的紧密耦合。

虽然我是域名数据不可知以及实施基于DDD的架构的其他良好做法的忠实粉丝,但我会说您仍然可以保留这些功能,而您不需要以这种方式耦合您的存储库。

顺便说一句,如果我正确理解了您的方法,我发现您的推理存在设计缺陷:sys.stdin = open('/dev/tty') import pdb; pdb.set_trace() 域对象,但它不是持久的对象,不是吗?存储库旨在与数据映射层协同工作,以持久保存域更改并提供不可知查询。

我读取您的代码的第一个结论是整个方法应该进入域服务,您可以在其中注入任意数量的存储库,因为它是正确的位置。

其次,还有一些可以简化事情的东西,它可能是您的最终解决方案:为什么不将BidderInfo转变为可持久的对象?

如果我认为您正在使用OR / M,我不应该猜错,对吗?因此,如果以正确的方式对其进行配置,则可以保留BidderInfo并将其自动填充到单个查询中(或者谁知道,但它将成为OR / M优化角色)。因此,您将创建整个BidderInfo,您将在其上简单地实现将在幕后调用OR / M的BidderInfoRepository

否则,您应将此代码放入服务层