RavenDB 4中BeforeStore事件在异步会话中无法触发?
RavenDB 4异步会话BeforeStore事件不触发的问题解决
嘿,我刚好了解这个问题,你碰到的情况其实是RavenDB 4早期RC版本的一个已知bug,再加上一点点使用方式的小问题,咱们一步步来解决:
问题原因
- 版本bug:你使用的
4.0.0-rc-40025是RavenDB 4的早期候选版本,这个版本里全局的DocumentStore.OnBeforeStore事件确实不会在异步会话中触发——这个问题在后续的正式发布版本中已经被修复了。 - 事件绑定时机:虽然不是核心原因,但你在
store.Initialize()之前绑定全局事件的方式,在某些场景下可能会出现事件订阅失效的情况,官方推荐的做法是初始化完成后再注册全局监听器。
解决方案
临时修复(不升级版本)
如果暂时没办法升级,你可以在每个异步会话创建后,手动订阅当前会话的BeforeStore事件,这样就能确保异步场景下事件被触发:
private static async Task<MyEntity> StoreEntityAsync(IDocumentStore store) { using (var session = store.OpenAsyncSession()) { // 给当前异步会话单独绑定BeforeStore事件 session.BeforeStore += (sender, eventArgs) => { if (eventArgs.Entity is MyEntity entity) entity.Description = DateTime.UtcNow.ToString(); }; var entity = new MyEntity { Name = "Async session" }; await session.StoreAsync(entity); await session.SaveChangesAsync(); return entity; } }
长期解决方案(推荐)
直接升级你的RavenDB Client和服务器到4.0正式版及以上,升级后你原来的全局事件绑定代码就能在同步和异步会话中都正常工作,不需要做额外修改。
另外,我再补充一个RavenDB 4官方推荐的全局监听器写法,这种方式比直接绑定OnBeforeStore事件更符合新版本的设计规范,而且在同步/异步场景下都能稳定运行:
// 实现IBeforeStoreListener接口 public class MyBeforeStoreListener : IBeforeStoreListener { public void BeforeStore(string database, EntityInfo entityInfo, object entity) { if (entity is MyEntity myEntity) myEntity.Description = DateTime.UtcNow.ToString(); } } // 在DocumentStore初始化后注册监听器 store = store.Initialize(); store.Listeners.RegisterListener(new MyBeforeStoreListener());
用这种方式替代直接绑定OnBeforeStore事件,不仅能解决当前的异步问题,还能让代码更符合RavenDB 4的设计理念,扩展性也更好。
验证效果
不管用哪种方案,修改后重新运行你的控制台程序,asyncEntity.Description都会被正确赋值,控制台不会再输出BeforeStore didn't run for asyncEntity.的提示了。
内容的提问来源于stack exchange,提问作者hakksor
相关产品推荐
相关产品推荐

