Уперт Словарь в MongoDb
Насколько мне известно, Mongodb знает Dictionary
как объект, и он не может выполнять никаких операций, связанных с массивом. Я изменил сериализацию и попробовал с сериализацией различного типа словаря. но нет шансов.
поэтому я загружаю свое поле (словарь)(все) в память, обновляю его и устанавливаю обратно в mongodb.
Есть ли способ вставить словарь в mongodb с помощью драйвера C#?
мой тип документа:
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});
}
Обратите внимание, что это просто добавит новый ключ / значения или обновит существующее, это ничего не удалит.