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
相关产品推荐
相关产品推荐

