2017-07-13 54 views
0

我想从ravendb中选择和更新多行,但它递归更新相同的行。即前100行。没有变化。Ravendb选择 - 更新多行

这是我的代码。我怎样才能选择一些行,更新每行的一些字段,并一次又一次地做,直到我的工作完成。

var currentEmailId = 100; 
using (var session = store.OpenSession()) 
{ 
    var goon = true; 
    while(goon){ 
      var contacts = session.Query<Contacts>().Where(f => f.LastEmailId < currentEmailId).Take(100); 
      if(contacts.Any()){ 
       foreach(var contact in contacts){ 
        EmailOperation.Send(contact, currentEmailId); 
        contact.LastEmailId = currentEmailId; 
       } 
      session.SaveChanges(); 
      } 
      else{ 
      goon = false 
      } 
    } 
} 

回答

1

这可能是因为你保存更改后,立即做了查询,而不让索引更新后保存更改。因此,你找回相同的物品。为了解决这个问题,你可以告诉SaveChanges等待索引更新。您的代码会是这个样子:

试试这个:

var goon = true; 
var currentEmailId = 100; 
while (goon) 
{ 
    using (var session = store.OpenSession()) 
    { 
     var contacts = session.Query<Contacts>() 
      .Where(f => f.LastEmailId < currentEmailId) 
      .Take(100); 

     if(contacts.Any()) 
     { 
      foreach(var contact in contacts) 
      { 
       EmailOperation.Send(contact, currentEmailId); 
       contact.LastEmailId = currentEmailId; 
      } 

      // Wait for the indexes to update when calling SaveChanges. 
      DbSession.Advanced.WaitForIndexesAfterSaveChanges(TimeSpan.FromSeconds(30), false); 
      session.SaveChanges(); 
     } 
     else 
     { 
      goon = false 
     } 
    } 
} 

如果要更新一次的联系人,你不妨考虑使用Streaming query resultsBulkInsert结合更新多个联系人的连接质量使用。

+0

does WaitForIndexesAfterSaveChanges是安全的吗?例如只有一秒钟。 –

+0

是的,它很安全。它会阻塞,直到适当的索引更新,这样你就不会查询陈旧的数据。 (我现在习惯于在我的生产应用中定期打电话。) –

+0

通常会更新多少个联系人?十?数百?成千上万的?正如我在帖子末尾提到的,如果您在调用此函数时更新多个联系人,则可能需要考虑Streaming + BulkInsert。它会更快,你不必处理陈旧的索引。 –