如何处理多层1对多关系的DAL?

Posted

技术标签:

【中文标题】如何处理多层1对多关系的DAL?【英文标题】:How to handle DAL for multiple layers of 1 to many relationship? 【发布时间】:2020-03-30 01:53:54 【问题描述】:

我有以下问题: 我有一个具有多层一对多关系的聚合根。

Root -> has many
Child -> has many
GrandChild

我有Controller\s 处理聚合根的每一层上完成的逻辑。

我不知道如何处理数据访问层。

我是否应该为聚合根创建一个存储库,所有ChildGrandChild 操作都通过它处理,或者为每个级别创建一个存储库就可以了?

此外,在我的例子中,GrandChildren 实体占用了大量空间(它们包含文本),因此我将使用文档数据库 - RavenDB

public class Root

  public int IDget;set;
  public IEnumerable<Child>Children;

public class Child

   public int ChildIDget;set;
   public IEnumerable<Child>GrandChildren; //occupy a loot of space !

public class GrandChild

  public int GrandChildIDget;set;


public interface IGenericRepository<T>

    bool Add<T>(T newValue);
    T Get<T>(int id);
    IEnumerable<T> GetAll();
    bool Delete(int id);   
    bool Update<T>(T value);

控制器

public class ParentController

    IGenericRepository<Root> repo;
    public IActionResult<Root> Get(int rootId)
    
         return this.repo.Get(rootId);
    
 
public class ChildControiller_V1

    IGenericRepository<Child>repo;
    public IActionResult<Child> Get(int childid)
    
          this.repo.Get(childid); //the id is unique 
    

通过根访问

 public class RootRepository:IGenericRepository<Root>
 
     /// implementations
     public IGenericRepository<Child> GetChildRepository()
     
            return //some implementation of IGenericRepository for Child
     
 
    public class ChildController_V2
    
        IGenericRepository<Root>repo;
        public IActionResult<Child> Get(int rootId,int childid)
        
              var root=this.repo.Get(rootId);
              var childRepo=root.GetChildRepository();
              var get= childRepo.Get(childId);

        
    

我希望你明白这一点。对于更多层,我会一直这样做。考虑到最低实体与其他实体相比占用大量空间,有什么好的方法?

更新

Root 将不得不支持Create,Delete - 这里不会发生太多事情Child 必须支持 Create,Delete - (重点将放在 GET ,类似于GET 5 children starting from index=10 这里)Grandchildren 必须支持完整的 CRUD 并在 Update 上进行大量密集工作。GrandChildren 的表大小将是 >>>>> 所有其他的组合。每个 Grandchild 将有一个纯文本柱子。 当我说tablecolumn 时,我指的是典型 SQ L 数据库中的等价物

【问题讨论】:

你好,我觉得这篇文章可以回答你的问题ayende.com/blog/96257/document-based-modeling-auctions-bids 你想支持什么样的查询?一般来说,除了上面的注释之外,您还可以创建递归地图索引来查询关系或使用较新版本的 Graph API 好吧,我将不得不支持create,delete 支持Parentcreate,delete,get 支持ChildCreate,Delete,Update and many others 支持Grandchild。正如我所说,密集的工作将在@ 上完成987654352@ ,以及GrandChildren >>>> 所有其他的表(尚不知道ravenDB中的等价物)大小。孙子将被集中编辑。 【参考方案1】:

从(经典)DDD 的角度来看,存储库返回完全物化的聚合,其中聚合代表一致性/事务边界。拥有子孙存储库意味着您放弃了它,并获得了 DDD 的一大好处。话虽如此,您需要确定一致性边界在哪里。实体之间是否存在约束?如果没有,它们可以有自己的聚合。请记住,聚合不会出现在其他聚合中,并且来自实体的引用应该只转到聚合根,而不是另一个聚合层次结构中的某个其他实体。

我已经在此处的回答中提到了其他一些可能有趣的点,特别是数据过多时的方向。 https://***.com/a/59189413/2613363

最后,我会说 Raven 有版本(etags)。如果您最终更新了许多子项,请使用它们。

【讨论】:

问题是,在我的RootChildGrandChild 层次结构中,我将有一个控制器来处理Child 级别的操作。例如get all children with index between [0,11] 请求者将使用这些 GrandChild-ren 中的 Child-ren ,因此它们在这种情况下是捆绑在一起的。然而,最密集的部分将是一个 controller ,它在 a 的上下文中处理 GrandChild-ren 的操作child.这些GrandChild实体构成了数据库最大的部分,也是使用最多的部分。 如果只是为了查询,没问题。如果您正在对孩子进行更改,您希望通过 root 进行更改(孙辈也是如此)。这是为了强制执行一致性边界。如果没有要执行的一致性/事务,那么也许它们不应该放在一起。链接更深入一点。

以上是关于如何处理多层1对多关系的DAL?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理mongodb中的多对多关系

如何处理 JSON 中的多对多关系?

如何处理淘汰视图模型中的多对多关系

Selenium 如何处理多层嵌套 iframe

如何处理 Redux 中的关系数据?

如何处理Rails加入表关系删除?