IRepository和关系数据

时间:2009-11-20 17:52:56

标签: design-patterns repository

我想知道推荐的方法是用IRepository模式处理关系数据。

我的数据库具有以下表格,其中列名称在括号中:

  • 计划(PlanId,Name,CreationDate, ModifiedDate,ViewId)
  • 区域(AreaId,Name,nTop,nLeft, nRight,nBottom)
  • 观看次数(ViewId,nTop,nLeft,nRight, nBottom)
  • PlanAreas(PlanId,AreaId)

每个计划可以有零个或多个区域但只有一个视图,因此Plans.ViewId是FK到Views.ViewId。在PlanAreas中,两列都是相应表格的FK。

有些时候,我的应用程序可能想要在这些区域独立行动,但通常我会同时加载,保存,删除计划及其所有组成部分(区域,视图)。

我已经开始了......

public interface IPlanRepository
{
   IEnumerable<MyModel.Plan> GetAll();
   MyModel.Plan GetByName(string sName);
   MyModel.Plan GetById(string sId);
   void Delete(MyModel.Plan plan);
   void SaveOrUpdate(MyModel.Plan plan);
}

public class Plan
{
   public Guid Id { get; set; }
   public string Name { get; set; }
   public DateTime Creation { get; set; }
   public DateTime Modified { get; set; }
   public MyModel.View View { get; set; }
   public IList<MyModel.Area> Areas { get; set; }
}

public class View
{
   public Guid Id { get; set; }
   public IEnvelope Envelope { get; set; } // encapsulates top, left, bottom, right
}

// etc.

该计划相当复杂,因此实际上会有更多属性,但这是一个良好的开端。所以现在提问:

  • 我需要IViewRepository和IAreaRepository吗?
  • 在IPlanRepository中实现方法时,我是否所有的工作都是抓取与计划相关的关系数据(即区域和视图)并返回完全填充的Plan对象?
  • 或者更好的是,在返回计划后,有一个更高级别的“聚合器”(缺少一个更好的词)会填充属性?像这样:

    Plan GetPlanById(string sId)
    {
        Plan myplan = new Plan();
        IPlanRepository planrepo = new PlanRepoImpl();
        myplan = planrepo.GetById(sId); 
        IViewRepository viewrepo = new ViewRepoImpl();
        myplan.View = viewrepo.GetByPlanId(sId);
        return myplan;
    }
    

现在我正计划使用LINQ-SQL进行数据访问,因为我对它很熟悉,而且我可以很快地完成它。我可能会切换到其他的东西,但我现在想保持简单。

3 个答案:

答案 0 :(得分:2)

如果您没有为计划的子部分做回购,您如何处理仅加载您需要的部分?例如,如果我想获得系统中所有计划的列表并选择一个详细查看,那么您绝对不希望返回完全填充的计划对象,只是为了显示摘要列表。这会在很多方面扼杀表现。相反,你只需要一个精益计划对象,也许还要计算它有多少个区域(而不是所有人口稠密的区域)。而且,除此之外,您还希望以可重用的通用方式完成所有这些工作。

我倾向于为您想要使用的每个主要实体的单独存储库的概念。然后通过某种聚合器管理那些之间的关系。或者,也许您将属性引用列表和关联的委托(或表达式树)传递给聚合根目录上的每个检索方法,以告诉它要填充哪些项目。但是你仍然存在二级,三级,四级等关系的问题。回到最初的想法,只需要显示计划列表和区域计数......你不会想要返回所有区域来获得计数。

这只是检索。如果您的计划有5个区域,并且每个区域都有一系列信封,并且您决定从区域添加,编辑或删除信封,该怎么办?当您处于计划级别时,您将如何走树以找出要更新的内容?似乎操纵信封和信封回购更有意义。

在我看来,repo处理数据检索,另一个引擎/类处理关系修复。

答案 1 :(得分:1)

您应该为每个Aggregate Root实现一个存储库。所以,在我看来,你只需要一个存储库。是的,我认为存储库应该负责构建一个包含所有相关数据的实体。

答案 2 :(得分:0)

您绝对不需要计划子部分的存储库。由于它们是模型的内部,因此您可能不需要直接访问它们,如果您这样做,您可能还需要参考该计划。

既然如此,您可能希望将计划作为主要参考点。使用完整填充的计划对象,您可以找到有关与其关联的区域和视图的任何信息。

编辑: 我最近一直在阅读Eric Evans的DDD book,并且他的存储库使用了与我上面描述的类似的风格。