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

时间:2016-12-27 09:42:42

标签: c#-4.0 ravendb

使用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()工作的最佳解决方案是什么(最好不必传递旧对象)?

2 个答案:

答案 0 :(得分:0)

  1. 如果我尝试将新对象与id相关联,为什么Raven会关心,只要新对象带有正确的电子标签并输入?
  2. RavenDB倾向于能够从内存中提供文档(速度更快)。通过检查相同id的持久对象,可以防止难以调试的错误。

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

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

      1. 使document.Update()工作的最佳解决方案是什么(最好不必传递旧对象)?
      2. 我去重构document.Update方法也有一个可选参数来接收旧日期,因为#1和#2似乎不可能。

答案 1 :(得分:-1)

RavenDB支持开箱即用的乐观并发。你唯一需要做的就是打电话。

session.Advanced.UseOptimisticConcurrency = true;

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