RavenDB嵌入式版与标准版Patch API差异及测试报错排查
RavenDB嵌入式版与标准版Patch API问题解惑
先给你把核心问题说清楚:
一、Patch API功能有没有差异?
完全没有!RavenDB的核心Patch API(不管是单文档Patch还是批量Patch)在嵌入式版和标准版里是一模一样的,官方设计的时候就保证了核心功能的一致性,不会因为是嵌入式运行就砍功能。唯一的小区别是嵌入式版是单机模式,没有集群相关的Patch分发逻辑,但这对你的测试场景完全没影响。
二、需要特殊配置启用Patch API吗?
不用!嵌入式版的Document Store默认就开着Patch功能,你只要按照常规方式初始化就行,比如:
var store = new DocumentStore { Urls = new[] { "memory://test-db" }, // 内存模式适合测试 Database = "TestDB" }.Initialize();
除非你自己修改了Conventions里的写操作限制,否则Patch肯定能用。
三、为啥你的测试会报「DocumentDoesNotExists」?
虽然你说文档肯定存在,但结合嵌入式版的特性,大概率是这几个坑:
- 事务没提交就Patch:嵌入式版的内存存储对事务隔离性很严格,如果你在一个事务里存了文档但没调用
SaveChanges(),然后在另一个事务里Patch,那这个Patch操作根本看不到未提交的文档,自然就报不存在了。- 解决:存完文档一定要执行
SaveChanges(),或者把存文档和Patch放在同一个事务里。
- 解决:存完文档一定要执行
- 文档ID大小写/格式不对:RavenDB的ID是大小写敏感的,嵌入式版在内存里校验得更严。比如你存的是
users/1,Patch用的是Users/1,那肯定找不到。- 解决:统一ID的写法,别随意修改大小写或格式。
- 测试里Store初始化重复了:如果每个测试用例都重新初始化一次Document Store,那每次都是新的空库,之前存的文档自然没了。
- 解决:把Store的初始化放在测试类的Setup方法里,整个测试类共用一个Store实例,测试完再清理数据。
给你贴个正确的测试代码参考:
[TestFixture] public class RavenDbPatchTests { private DocumentStore _store; [SetUp] public void Setup() { // 初始化一次,整个测试类复用 _store = new DocumentStore { Urls = new[] { "memory://test" }, Database = "TestDB" }.Initialize(); } [TearDown] public void TearDown() { // 测试完清理数据库 _store.Maintenance.ForDatabase("TestDB").Send(new DeleteDatabasesCommand(new DeleteDatabasesParameters { DatabaseNames = new[] { "TestDB" }, HardDelete = true })); _store.Dispose(); } [Test] public void PatchExistingDocument_ShouldSucceed() { // 先存文档并提交 using (var session = _store.OpenSession()) { session.Store(new User { Id = "users/1", Name = "Alice" }); session.SaveChanges(); } // 执行Patch using (var session = _store.OpenSession()) { var result = session.Advanced.Patch<User>("users/1", u => u.Name = "Bob"); Assert.That(result.Status, Is.EqualTo(PatchStatus.Patched)); session.SaveChanges(); } // 验证结果 using (var session = _store.OpenSession()) { var user = session.Load<User>("users/1"); Assert.That(user.Name, Is.EqualTo("Bob")); } } private class User { public string Id { get; set; } public string Name { get; set; } } }
内容的提问来源于stack exchange,提问作者PiotrB
相关产品推荐
相关产品推荐

