DDD,如何使用NHibernate在子实体上持久化删除?

DDD,如何使用NHibernate在子实体上持久化删除?,nhibernate,architecture,software-design,Nhibernate,Architecture,Software Design,拥有AggregateRoot和子实体列表,在删除或更新其中一个子实体后,如何持久化更新后的子实体列表 这是一个应用层服务 async Task HandleAsync(RemoveChildRequest request) { Aggregate aggregate = await _aggregateRepository.GetByIdAsync(request.AggregateId); aggregate.Remove

拥有AggregateRoot和子实体列表,在删除或更新其中一个子实体后,如何持久化更新后的子实体列表

这是一个应用层服务

  async Task HandleAsync(RemoveChildRequest request)
        {
            Aggregate aggregate = await _aggregateRepository.GetByIdAsync(request.AggregateId);

            aggregate.RemoveChild(request.ChildId);

            await _aggregateRepository.Update(aggregate);

            await _unitOfWork.CommitAsync();
        }
这是删除子项的聚合方法

    public virtual void RemoveChild(Guid ChildId)
    {
        Child kid = _children.Single(item => item.Id == ChildId);

        _children.Remove(kid);
    }
这是存储库 聚合与它应该的一样,具有相同的数据,但没有子级,它已从集合中删除

Update(Aggregate aggregate)
{
      await Session.UpdateAsync(aggregate, aggregate.Id);
}
这是我的NHibernate配置

  mapping
      .HasMany<Children>(Reveal.Member<Aggregate>("Children"))
      .Not.Inverse()
      .Not.KeyNullable()
      .Not.KeyUpdate()
      .Cascade.Delete();
但据我所知,存储库应该是特定于聚合的

我感兴趣的是将实际保留对数据存储的更改的代码是什么样子的?如何移除该儿童。存储库。

如果子实体属于聚合根,即组合而不是关联,则必须通过AggregateRoot而不是独立地删除或添加子实体。此外,儿童应该是价值对象,而不是自身权利的集合体

因此,您是对的—存储库将只获取父级。然后,您可以使用RemoveChild命令对该实例执行操作,并发布一个ChildRemoved事件,该事件会将该子对象从列表中移除。

在这里找到了我的答案

这里呢

NHibernate构型

    mapping
        .HasMany<Child>(Reveal.Member<Order>("Children"))
        .Access.LowerCaseField(Prefix.Underscore)
        .Cascade.AllDeleteOrphan()
        .Not.KeyNullable()
        .Not.KeyUpdate();

下面是使用字节码映射的方法,重要的是colmap.cascade.All。我希望这有帮助

public class Client
{
    public virtual int ClientId { get; protected set; }
    public virtual string ClientName { get; protected set; }
    public virtual IList<ClientLocation> ClientLocations { get; protected set; }

    protected Client()
    {
        this.ClientLocations = new List<ClientLocation>();
    }
}

public class ClientLocation
{
    public virtual int ClientLocationId { get; protected set; }
    public virtual Client Client { get; protected set; }
    public virtual string LocationName { get; protected set; }

    protected ClientBranch()
    {
    }
}
映射

public class ClientMap : ClassMapping<Client>
{        
    public ClientMap() {
    Lazy(true);

        Id(x => x.ClientId, map => map.Generator(Generators.Identity));
    Property(x => x.ClientName);

        Bag(x => x.ClientLocations, colmap => { colmap.Key(x => x.Column("CLIENTID")); colmap.Cascade(Cascade.All); }, map => { map.OneToMany(); });
    }
}


public class ClientLocationMap : ClassMapping<ClientLocation>
{
    public ClientLocationMap()
    {
    Lazy(true);

        Id(x => x.ClientLocationId, map => map.Generator(Generators.Identity));
    Property(x => x.LocationName);

        ManyToOne(x => x.Client, map => { map.Column("CLIENTID"); map.NotNullable(true); map.Cascade(Cascade.All); });
    }
}

@AlessandroSantini内部聚合对象可以是实体,而不必是值对象。另外,最初的问题没有提到命令或事件的使用。我认为答案不应该暗示这些。可能是重复的
public class Client
{
    public virtual int ClientId { get; protected set; }
    public virtual string ClientName { get; protected set; }
    public virtual IList<ClientLocation> ClientLocations { get; protected set; }

    protected Client()
    {
        this.ClientLocations = new List<ClientLocation>();
    }
}

public class ClientLocation
{
    public virtual int ClientLocationId { get; protected set; }
    public virtual Client Client { get; protected set; }
    public virtual string LocationName { get; protected set; }

    protected ClientBranch()
    {
    }
}
public class ClientMap : ClassMapping<Client>
{        
    public ClientMap() {
    Lazy(true);

        Id(x => x.ClientId, map => map.Generator(Generators.Identity));
    Property(x => x.ClientName);

        Bag(x => x.ClientLocations, colmap => { colmap.Key(x => x.Column("CLIENTID")); colmap.Cascade(Cascade.All); }, map => { map.OneToMany(); });
    }
}


public class ClientLocationMap : ClassMapping<ClientLocation>
{
    public ClientLocationMap()
    {
    Lazy(true);

        Id(x => x.ClientLocationId, map => map.Generator(Generators.Identity));
    Property(x => x.LocationName);

        ManyToOne(x => x.Client, map => { map.Column("CLIENTID"); map.NotNullable(true); map.Cascade(Cascade.All); });
    }
}