为什么这个代码(尝试)用第二个对象覆盖我的第一个对象?我的第一个对象具体为Id的"StringBasedIdClasses/1",第二个没有提供Id,所以Raven应该生成一个未使用的Id,不应该吗?
var quickStore = new EmbeddableDocumentStore() { RunInMemory = true };
quickStore.Initialize();
quickStore.RegisterListener(new DocumentConversionListener()).RegisterListener(new DocumentStoreListener());
using (var session = quickStore.OpenSession())
{
session.Advanced.UseOptimisticConcurrency = true;
var stringIdTest = new StringBasedIdClass()
{
Id = "StringBasedIdClasses/1",
Name = "StringItem1"
};
session.Store(stringIdTest);
session.SaveChanges();
}
using (var session = quickStore.OpenSession())
{
session.Advanced.UseOptimisticConcurrency = true;
var stringIdTest = new StringBasedIdClass()
{
Name = "DidIReplaceYou"
};
session.Store(stringIdTest);
session.SaveChanges();//This fails with a ConcurrencyViolation as I use OptimisticConcurrency and have Etag support on my objects
}
Run Code Online (Sandbox Code Playgroud)
一切都在使用文档存储的一个当前实例.这似乎很基本所以一定要错过一些简单的东西.
好吧,答案部分是托马斯所说的,但更具体地说,RavenDb完全忽略了你手动插入的ID.为了进行批量导入(比如从旧系统到新系统的数据迁移,就像我正在做的那样,您需要执行以下操作:
在导入结束时,使用以下代码将集合的hilo(基本上是新ID的起点)设置为高于系统中现在最高id的值:
session.Store(new {Id = "Raven/Hilo/{yourcollectionname}", Max = newMaxValue});
session.SaveChanges();
Run Code Online (Sandbox Code Playgroud)现在,当您初始化新商店时,将使用正确的hilo值.
请注意,此过程无法使用内存版本进行模拟,EmbeddableDocumentStore因为您每次打开商店时实际上都会创建一个全新的服务器实例.因此,如果您尝试使用现有/非现有记录的已知ID进行集成测试,则必须让Raven选择ID而不将它们设置在您自己的对象中.这应该可以正常工作,因为你的新内存存储总是从1开始.为了确保隔离我的测试,我为每个测试开了一个新商店.