Mongo db C#update.SetWrapped方法不调用Custom Bson Serializer

时间:2014-09-04 12:02:15

标签: c# mongodb serialization mongodb-.net-driver

我已经实现了一个自定义Bson Serializer,这个Custom BsonSerializer似乎在Save和获取mongo文件时工作正常。但是当尝试进行更新时,似乎并没有调用序列化程序。

仅供参考, 我添加了DecimalSerializer,它将十进制序列化为Int32值,并在反序列化时将其转换回Decimal值。因此,在更新十进制值时,它不会调用任何序列化程序。

更新语句:Update.SetWrapped("Tiers.$.Price", tier.Price),这将在mongo db中保存为字符串类型。

1 个答案:

答案 0 :(得分:0)

似乎驱动程序的某些版本不会在Update

上运行bson序列化程序

https://github.com/mongodb/mongo-csharp-driver/blob/e455c963cb385b94fdcd02d1e53b536b47663239/src/MongoDB.Driver/MongoCollection.cs

    public virtual WriteConcernResult Update(IMongoQuery query, IMongoUpdate update, MongoUpdateOptions options)
    {
        var updateBuilder = update as UpdateBuilder;
        if (updateBuilder != null)
        {
            if (updateBuilder.Document.ElementCount == 0)
            {
                throw new ArgumentException("Update called with an empty UpdateBuilder that has no update operations.");
            }
        }

        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var queryDocument = query == null ? new BsonDocument() : query.ToBsonDocument();
        var updateDocument = update.ToBsonDocument();
        var messageEncoderSettings = GetMessageEncoderSettings();
        var isMulti = options.Flags.HasFlag(UpdateFlags.Multi);
        var isUpsert = options.Flags.HasFlag(UpdateFlags.Upsert);
        var writeConcern = options.WriteConcern ?? _settings.WriteConcern ?? WriteConcern.Acknowledged;

        var operation = new UpdateOpcodeOperation(_collectionNamespace, queryDocument, updateDocument, messageEncoderSettings)
        {
            IsMulti = isMulti,
            IsUpsert = isUpsert,
            WriteConcern = writeConcern
        };

        using (var binding = _server.GetWriteBinding())
        {
            return operation.Execute(binding, Timeout.InfiniteTimeSpan, CancellationToken.None);
        }
    }

但确实发生在保存

    public virtual WriteConcernResult Save(Type nominalType, object document, MongoInsertOptions options)
    {
        if (nominalType == null)
        {
            throw new ArgumentNullException("nominalType");
        }
        if (document == null)
        {
            throw new ArgumentNullException("document");
        }

        var serializer = BsonSerializer.LookupSerializer(document.GetType());

这对我来说真的源于这样一个事实,即序列化程序可能必须拥有整个对象,并且在进行更新时,整个对象永远不会到达客户端。这很可能是预期的。你的选择:

  1. 在setWrapped
  2. 之前手动序列化tier.Price
  3. 检查另一个版本的驱动程序是否有效(可能不值得)
  4. 对MongoDB问题的错误报告(Github页面上的信息)
  5. 避免对十进制类型使用自定义序列化程序(BSON本身具有双数据类型)