You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Marten DB启用快照与软删除报错,能否共存及实现方案?

问题解答

可以同时为Marten聚合根启用软删除与快照,但不能直接使用Marten内置的Snapshot<MyAggregate>方法——因为内置的AggregateProjection设计上未兼容软删除逻辑,因此会抛出你遇到的错误。需要通过自定义快照投影来实现两者共存。

解决步骤

1. 确保聚合根包含软删除标记属性

你的MyAggregate需要有一个用于标记软删除的属性(比如IsDeleted):

public class MyAggregate
{
    public Guid Id { get; set; }
    public bool IsDeleted { get; set; }
    // 其他聚合属性...
}

2. 自定义快照投影类

创建继承自AggregateProjection<MyAggregate>的自定义投影,手动处理软删除事件与快照状态同步:

public class MyAggregateSnapshotProjection : AggregateProjection<MyAggregate>
{
    public MyAggregateSnapshotProjection()
    {
        // 关联聚合的删除事件(替换为你实际的删除事件类型)
        DeleteEvent<MyAggregateDeleted>(e => e.AggregateId);
    }

    public override MyAggregate Apply(MyAggregate state, IEvent evt)
    {
        var updatedState = base.Apply(state, evt);
        
        // 当触发删除事件时,标记快照为软删除
        if (evt is MyAggregateDeleted)
        {
            updatedState.IsDeleted = true;
        }

        return updatedState;
    }
}

3. 修改Marten配置

替换内置快照注册方式,改用自定义投影,并正确配置软删除:

public static class StoreOptionsExtensions
{
    public static void ConfigureEventStore(this StoreOptions options)
    {
        // 配置软删除,指定聚合根的软删除标记属性
        options.Schema.For<MyAggregate>().SoftDeleted(x => x.IsDeleted);
        
        // 注册自定义快照投影,指定生命周期(这里用Inline和原配置一致)
        options.Projections.Add(new MyAggregateSnapshotProjection(), ProjectionLifecycle.Inline);
    }
}

关键说明

  • Marten 6.x的内置快照投影未处理软删除逻辑,因此必须通过自定义投影来同步软删除状态到快照中。
  • 自定义投影需要明确关联聚合的删除事件,确保快照能正确捕获软删除状态,避免查询时出现数据不一致。

内容的提问来源于stack exchange,提问作者Sara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:22:12