我使用MongoDB的C#驱动程序并尝试编辑一些MongoDB元素。在反序列化BSON时,我使用[IgnoreExtraElements]标记来过滤掉我并不真正关心编辑的字段。问题是当我尝试将元素序列化回Mongo数据库时。而不是只更改我编辑过的字段,序列化元素会覆盖整个对象。
例如,我正在使用C#属性更改Word元素:
[BsonId]
public ObjectId _id;
public string word;
在MongoDB中它还有元素" conjugations",这是一种我不想序列化或混乱的复杂数组。但是,当我尝试类似于下面的代码时,它会消除绑定数组。
MongoWord word = collection.FindOneAs<MongoWord>(Query.EQ("word","hello"));
word.word = "world";
collection.Save(word);
如何避免覆盖Json数据库中的额外字段?现在我正在尝试编写一个Update.Set构建器查询,并且只更新我使用Reflection / Generics更改的字段..是否有一些像反向[IgnoreExtraElements]或更新设置那样容易的事情我是&#39 ;我在这里失踪了?
答案 0 :(得分:0)
这就是必须手动指定IgnoreExtraElements的原因。您基本上选择了可能会丢失数据。
处理此问题的正确方法是实际支持额外的元素。您可以在文档中查看此部分,了解如何执行此操作:http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/#supporting-extra-elements
答案 1 :(得分:0)
这是我最终使用的功能。我不想使用[BsonExtraElements],因为如果没有编辑,似乎没有必要再次删除ExtraElements来保存它们。相反,我使用mongo UpdateBuilder只更新我从mongo更改/删除的字段。如果我需要通过将字段设置为null来清除字段,那么解决方案就会出现问题。
/// <summary>
/// Update a Mongo object without overwriting columns C# think are null or doesn't know about
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model">The mongo object to update</param>
/// <param name="collection">The collection the object should go in</param>
/// <param name="objectId">The Bson ObjectId of the existing object in collection</param>
public void UpdateNotNullColumns<T>(T model, MongoCollection<T> collection, ObjectId objectId)
{
if (objectId==default(ObjectId))
{
return;
}
else
{
//Build an update query with all the non null fields using reflection
Type type = model.GetType();
FieldInfo[] fields = type.GetFields();
UpdateBuilder builder = new UpdateBuilder();
foreach(var field in fields)
{
BsonValue bsonValue = BsonValue.Create(field.GetValue(model));
if(bsonValue!=null)
{
Type bsonType = bsonValue.GetType();
builder.Set(field.Name, bsonValue);
}
}
//Actually update!
collection.Update(Query.EQ("_id", objectId), builder);
}
}