2017-01-16 12 views
2

私の知る限りでは、mongodbはDictionaryをオブジェクトとして認識し、配列に関係する操作はできません。私は逐次化を変更し、さまざまな種類の辞書の逐次化を試みました。しかし、チャンスはありません。
私は自分のフィールド(辞書)(​​全体)をメモリに読み込み、更新してmongodbに戻します。
upsert辞書とmongodbのC#のドライバはありますか?Upsert辞書をMongoDbで


私のドキュメントタイプ:

public class Site 
    { 
     public string Id { get; set; } 
     //[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)] 
     public Dictionary<string,string> Properties { get; set; } 
    } 

私の更新操作:

public ServiceResult UpdateProperties(string id, Dictionary<string,string> properties) 
     { 
      var baseList = Collection.Find(m => m.Id == id) 
       .Project(s => s.Properties) 
       .FirstOrDefault(); 

      if (baseList == null) 
      { 
       baseList = properties; 
      } 
      else 
      { 
       baseList.Upsert(properties); //update,insert dic by new one 
      } 

      var filter = Builders<Site>.Filter 
       .Eq(m => m.Id, id); 

      var update = Builders<Site>.Update 
       .Set(m => m.Properties, baseList); 

      try 
      { 
       Collection.UpdateOne(filter, update); 

       return ServiceResult.Okay(Messages.ItemUpdated); 

      } 
      catch (Exception ex) 
      { 
       return ServiceResult.Exception(ex); 
      }  
     } 

私は本当にあなたが提供することができます任意の助けに感謝。


一義:

public static class DictionaryExtensions 
    { 
     public static void Upsert<TKey, TValue>(this Dictionary<TKey, TValue> source, 
              Dictionary<TKey, TValue> newOne) 
     { 
      foreach (var item in newOne) 
      { 
       source[item.Key] = item.Value; 
      } 
     } 
    } 

答えて

1

あなたが挿入/更新したいすべてのプロパティを通過し、各プロパティのためにそれを行うことができます:複数で、答えの

UpdateDefinition<Site> upsert = null; 
if (properties.Any()) 
{ 
    var firstprop = properties.First(); 
    upsert = Builders<Site>.Update.Set(nameof(Site.Properties) + "." + firstprop.Key, 
           firstprop.Value); 

    foreach (var updateVal in properties.Skip(1)) 
    { 
     upsert = upsert.Set(nameof(Site.Properties) + "." + updateVal.Key, 
              updateVal.Value); 
    } 

    collection.UpdateOne(r => r.Id == "YourId", upsert, 
               new UpdateOptions { IsUpsert = true }); 
} 

前のバージョン更新:

foreach (var updateVal in properties) 
{ 
    collection.UpdateOne(r => r.Id == "YourId", 
     Builders<Site>.Update.Set(nameof(Site.Properties)+ "." + updateVal.Key, 
            updateVal.Value), 
            new UpdateOptions { IsUpsert = true}); 
} 

新しいKey/Valuesを追加するか、既存のものを更新するだけで、何も削除されません。

+0

です。本当に良いポイントの男。複数の接続(更新用)を避けるための提案はありますか。これまではこれが私にとって受け入れられる答えです。 – Soren

+0

私は答えを更新しました。これは一度だけ更新を実行します:) –

+0

は魅力的です。あなたの時間と配慮に感謝します。 – Soren