我想知道推荐的方法是用IRepository模式处理关系数据。
我的数据库具有以下表格,其中列名称在括号中:
每个计划可以有零个或多个区域但只有一个视图,因此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.
该计划相当复杂,因此实际上会有更多属性,但这是一个良好的开端。所以现在提问:
或者更好的是,在返回计划后,有一个更高级别的“聚合器”(缺少一个更好的词)会填充属性?像这样:
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进行数据访问,因为我对它很熟悉,而且我可以很快地完成它。我可能会切换到其他的东西,但我现在想保持简单。
答案 0 :(得分:2)
如果您没有为计划的子部分做回购,您如何处理仅加载您需要的部分?例如,如果我想获得系统中所有计划的列表并选择一个详细查看,那么您绝对不希望返回完全填充的计划对象,只是为了显示摘要列表。这会在很多方面扼杀表现。相反,你只需要一个精益计划对象,也许还要计算它有多少个区域(而不是所有人口稠密的区域)。而且,除此之外,您还希望以可重用的通用方式完成所有这些工作。
我倾向于为您想要使用的每个主要实体的单独存储库的概念。然后通过某种聚合器管理那些之间的关系。或者,也许您将属性引用列表和关联的委托(或表达式树)传递给聚合根目录上的每个检索方法,以告诉它要填充哪些项目。但是你仍然存在二级,三级,四级等关系的问题。回到最初的想法,只需要显示计划列表和区域计数......你不会想要返回所有区域来获得计数。
这只是检索。如果您的计划有5个区域,并且每个区域都有一系列信封,并且您决定从区域添加,编辑或删除信封,该怎么办?当您处于计划级别时,您将如何走树以找出要更新的内容?似乎操纵信封和信封回购更有意义。
在我看来,repo处理数据检索,另一个引擎/类处理关系修复。
答案 1 :(得分:1)
您应该为每个Aggregate Root实现一个存储库。所以,在我看来,你只需要一个存储库。是的,我认为存储库应该负责构建一个包含所有相关数据的实体。
答案 2 :(得分:0)
您绝对不需要计划子部分的存储库。由于它们是模型的内部,因此您可能不需要直接访问它们,如果您这样做,您可能还需要参考该计划。
既然如此,您可能希望将计划作为主要参考点。使用完整填充的计划对象,您可以找到有关与其关联的区域和视图的任何信息。
编辑: 我最近一直在阅读Eric Evans的DDD book,并且他的存储库使用了与我上面描述的类似的风格。