如何从数据库而不是内存中加载文档

How to load document out of database instead of memory

使用 Raven 客户端和服务器 #30155。我基本上在控制器中执行以下操作:

public ActionResult Update(string id, EditModel model)  
{
   var store = provider.StartTransaction(false);
   var document = store.Load<T>(id);
   model.UpdateEntity(document) // overwrite document property values with those of edit model.
   document.Update(store); // tell document to update itself if it passes some conflict checking
}

然后在 document.Update 中,我尝试这样做:

var old = store.Load<T>(this.Id);

if (old.Date != this.Date)
{
     // Resolve conflicts that occur by moving document period
}

store.Update(this);

现在,我 运行 解决了 old 加载内存而不是数据库并且已经包含更新值的问题。因此,它永远不会进入冲突检查。

我尝试通过将 Controller.Update 方法更改为:

来解决该问题
public ActionResult Update(string id, EditModel model)  
    {
       var store = provider.StartTransaction(false);
       var document = store.Load<T>(id);
       store.Dispose();
       model.UpdateEntity(document) // overwrite document property values with those of edit model.
       store = provider.StartTransaction(false);
       document.Update(store); // tell document to update itself if it passes some conflict checking
    }

这导致我得到一个 Raven.Client.Exceptions.NonUniqueObjectException 文本:Attempted to associate a different object with id

现在,问题:

  1. 如果我尝试将新对象与 id 相关联,只要新对象带有正确的电子标签和类型,为什么 Raven 会关心?

  2. 是否可以在其数据库状态下加载文档(覆盖默认行为以从内存中获取文档(如果存在)?

  3. 什么是让 document.Update() 工作的好解决方案(最好不必传递旧对象)?

RavenDB 开箱即用地支持乐观并发。您唯一需要做的就是调用它。

session.Advanced.UseOptimisticConcurrency = true;

参见: http://ravendb.net/docs/article-page/3.5/Csharp/client-api/session/configuration/how-to-enable-optimistic-concurrency

  1. 如果我尝试将新对象与 id 相关联,只要新对象带有正确的电子标签和类型,为什么 Raven 会关心?

RavenDB 依赖于能够从内存中提供文档(速度更快)。通过检查相同 ID 的持久对象,可以防止难以调试的错误。

编辑:请参阅下面 Rayen 的评论。如果在 Store 中启用并发检查/提供 etag,则可以绕过该错误。

  1. 是否可以在其数据库状态下加载文档(覆盖默认行为以从内存中获取文档(如果存在))?

显然不是。

  1. 什么是让 document.Update() 工作的好解决方案(最好不必传递旧对象)?

我重构了 document.Update 方法,使其也有一个可选参数来接收旧日期期间,因为 #1 和 #2 似乎不可能。