繁体   English   中英

在MongoDB C#2.0中允许Int32溢出(新驱动程序)

[英]Allow Int32 Overflow in MongoDB C# 2.0 (New Driver)

我有一个uint32来序列化到MongoDB。

我曾经能够使用https://jira.mongodb.org/browse/CSHARP-252中的以下代码执行此操作

public class AlwaysAllowUInt32OverflowConvention : ISerializationOptionsConvention
{
    public IBsonSerializationOptions GetSerializationOptions(MemberInfo memberInfo)
    {
        Type type = null;
        var fieldInfo = memberInfo as FieldInfo;
        if (fieldInfo != null)
        {
            type = fieldInfo.FieldType;
        }
        var propertyInfo = memberInfo as PropertyInfo;
        if (propertyInfo != null)
        {
            type = propertyInfo.PropertyType;
        }


        if (type == typeof(uint))
        {
            return new RepresentationSerializationOptions(BsonType.Int32) { AllowOverflow = true };
        }
        else
        {
            return null;
        }
    }
}

但是在新的MongoDB库中, ISerializationOptionsConventionRepresentationSerializationOptions不存在。 我已经看过了,看不出如何注册默认的ConventionPack(?)以允许uint32在新库上溢出int32。

如何在不向我的POCO 添加BsonRepresentation属性的情况下执行此操作?

有两种方法我可以想到你可以做到这一点。 可能最简单的方法是简单地为类型UInt32注册一个适当配置的序列化器,如下所示:

var uint32Serializer = new UInt32Serializer(BsonType.Int32, new RepresentationConverter(true, true));
BsonSerializer.RegisterSerializer(uint32Serializer);

如果你想使用约定( 只有在自动映射类时才适用),你可以这样做:

public class AlwaysAllowUInt32OverflowConvention : IMemberMapConvention
{
    public string Name
    {
        get { return "AlwaysAllowUInt32Overflow"; }
    }

    public void Apply(BsonMemberMap memberMap)
    {
        if (memberMap.MemberType == typeof(UInt32))
        {
            var uint32Serializer = new UInt32Serializer(BsonType.Int32, new RepresentationConverter(true, true));
            memberMap.SetSerializer(uint32Serializer);
        }
    }
}

并注册这样的约定:

var alwaysAllowUInt32OverflowConvention = new AlwaysAllowUInt32OverflowConvention();
var conventionPack = new ConventionPack();
conventionPack.Add(alwaysAllowUInt32OverflowConvention);
ConventionRegistry.Register("AlwaysAllowUInt32Overflow", conventionPack, t => true);

你可以通过IBsonSerializer来做到这一点

public class UInt32ToInt64Serializer : IBsonSerializer
{
    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return (uint)context.Reader.ReadInt64();
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        context.Writer.WriteInt64((uint)value);
    }

    public Type ValueType { get { return typeof (uint); } }
}

和序列化应该注册

BsonSerializer.RegisterSerializer(typeof(uint), new UInt32ToInt64Serializer());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM