2017-07-13 9 views
0

ravendbから複数の行を選択して更新しようとしていますが、再帰的に同じ行が更新されています。すなわち最初の100行。変更はありません。Ravendb select - 複数行更新

ここに私のコードです。いくつかの行を選択して、各行のいくつかのフィールドを更新し、私の仕事が終了するまで何度も何度もやり直します。

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に指示することができます。あなたが一度に多くの連絡先を更新している場合は、マスエン多くのコンタクトを更新するBulkInsertと組み合わせStreaming query resultsを使用して使用することを検討したいと思うかもしれ

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 
     } 
    } 
} 

はこれを試してください:あなたのコードは次のようになります。

+0

WaitForIndexesAfterSaveChangesは安全ですか?たとえば1秒間だけです。 –

+0

ええ、それは安全です。適切なインデックスが更新されるまでブロックされ、失効したデータをクエリしません。 (私は今、私のプロダクションアプリでこれをかなり頻繁に呼び出す習慣になっています) –

+0

通常、更新される連絡先の数はいくつですか? Tens?百人?何千?投稿の最後に述べたように、この関数が呼び出されるたびに多くの連絡先を更新する場合は、Streaming + BulkInsertを検討するとよいでしょう。それは速くなり、失効したインデックスに対処する必要はありません。 –