【问题标题】:Persisting only parts of large entities though repository通过存储库仅保留大型实体的一部分
【发布时间】:2011-11-28 07:19:40
【问题描述】:

我有一个实体,它是一个聚合根并包含许多子实体。基本上,从数据库中加载它并将其全部持久化是一项非常昂贵的操作。大多数时候,我只更改实体的一小部分,因此实际上不需要加载和持久化整个实体。但是,我不确定如何使用 DDD 原则和存储库模式来实现这一点。

我一直在考虑类似的事情:

interface IAggregateRoot {
    string Id { get; }

    ISubEntityA EntityA { get; }
    IList<ISubEntityB> EntityB { get; }
}

interface ISubEntityA {
    string Id { get; }

    int Foo { get; set; }
}

interface ISubEntityB {
    string Id { get; }

    string Bar { get; set; }
}

interface IRepository {
    IAggregateRoot Get(string rootId);
    ISubEntityA Get(string rootId);
    IList<ISubEntityB> Get(string rootId, int offset, int pageSize, out int numPages);

    ISubEntityB Find(string rootId, some specification to select a single ISubEntityB);

    // I can update either the entire aggregate root or an individual sub entity using
    // these methods.
    void AddOrUpdate(IAggregateRoot root);
    void Update(string rootId, ISubEntityA a);
    void Update(string rootId, ISubEntityB b);
}

这种方法有什么问题吗?有没有关于这个“问题”的最佳实践?

【问题讨论】:

    标签: c# domain-driven-design repository repository-pattern ddd-repositories


    【解决方案1】:

    我使用类似的技术。例如,假设我激活了一个帐户:

    var account = repository.Get(accountId);
    
    account.Activate();
    
    repository.AccountActivated(); // or repository.SaveActivationDetails()
    

    由于您不希望您的存储库涉及域行为,因此您不会执行以下操作:

    repository.ActivateAccount(account);
    

    但你可以这样做:

    account.Activate(repository); // in the Activate method the relevant repository 
                                  // persistence method will be invoked.
    

    所以你可以选择一个你觉得舒服的机制。

    但是回到您的存储库:我不会进行查询。轻量级查询层可以返回像DataTable 这样简单的东西供您的前端使用;其他 DTO。这与您要去那里的寻呼有关。

    【讨论】:

      【解决方案2】:

      存储库只处理聚合根而不处理它的一部分。所以我建议这个

      interface IRepository {
      IAggregateRoot Get(string rootId);
      //ISubEntityA Get(string rootId); <- this you get from the AR
      //IList<ISubEntityB> Get(string rootId, int offset, int pageSize, out int numPages);
       //for the method above I suggest a different repository and model dedicated for view
      
      // ISubEntityB Find(string rootId, some specification to select a single ISubEntityB);
      
      // I can update either the entire aggregate root or an individual sub entity using
      // these methods.
      void Save(IAggregateRoot root); // repository should know if to insert or update, by comparing to the existing instance, use of an OR\M recommended
      //    void Update(string rootId, ISubEntityA a); <- this should be handled by the method above
      //  void Update(string rootId, ISubEntityB b); <- this too
      }
      

      【讨论】:

        猜你喜欢
        • 2015-03-01
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        • 2015-04-14
        • 1970-01-01
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多