串行化BSON时不要覆盖额外的字段?

时间:2014-08-22 15:30:45

标签: mongodb-.net-driver

我使用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 ;我在这里失踪了?

2 个答案:

答案 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);
        }
    }