为了账号安全,请及时绑定邮箱和手机立即绑定

在 c# mongodb 驱动程序中,如何将序列化程序中的 dateOnly

在 c# mongodb 驱动程序中,如何将序列化程序中的 dateOnly

C#
幕布斯6054654 2022-06-19 10:22:34
我有一个具有类型属性(假设它被称为X)的模型DateTime?。我想设置,[BsonDateTimeOptions(DateOnly = true)]但在 mongo c# 驱动程序中使用类映射器,如:BsonClassMap.RegisterClassMap<MyModel>(cm =>{    cm.AutoMap();    cm.MapMember(c => c.X).SetSerializer(new DateTimeSerializer(dateOnly: true));});但由于某种原因,我收到一个错误,因为该属性是Nullable,对于普通DateTime类型,它可以正常工作。为什么我需要这个,因为我X只需要在没有时区的情况下将值保存为日期。我已经尝试构建自定义序列化程序,但是在反序列化时出现错误:ReadBsonType 只能在 State 为 Type 时调用,不能在 State 为 Value 时调用这是自定义序列化程序:public class DateTimeNullableSerialzier : DateTimeSerializer, IBsonSerializer{    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)    {        if (context.Reader.CurrentBsonType == BsonType.Null)            return null;        return base.Deserialize(context, args);    }    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)    {        if (value is null)            context.Writer.WriteNull();        else            base.Serialize(context, args, (DateTime)value);    }}
查看完整描述

2 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

如果有人正在阅读这篇文章并遇到同样的问题,那么实际上有一种方法可以在不实现自己的序列化程序的情况下做到这一点。不过,这是 2.x 版本的驱动程序。


默认情况下,mongo 将NullableSerializer<T>用于您的DateTime?字段,但默认情况下没有设置 dateOnly。但是,NullableSerializer<T>只需为该<T>类型包装一个普通的序列化程序,并且有一种方法可以为其提供您自己配置为使用 dateOnly 的实例:


var dateSerializer = new DateTimeSerializer(dateOnly: true);

var nullableDateOnlySerializer = new NullableSerializer<DateTime>().WithSerializer(dateSerializer));

BsonClassMap.RegisterClassMap<MyModel>(cm =>

{

    cm.AutoMap();

    cm.MapMember(c => c.X).SetSerializer(nullableDateOnlySerializer);

});


查看完整回答
反对 回复 2022-06-19
?
白衣非少年

TA贡献1155条经验 获得超0个赞

实际上,我如何实现序列化程序是问题所在,在进行了一些修复后,它可用于任何可为空的 DateTime 属性(DateTime?)并接受与中相同的构造函数参数DateTimeSerializer(但由于某种原因不适用于 DateTime 类型):


public class DateTimeNullableSerializer : IBsonSerializer

{

    public Type ValueType { get; }

    private DateTimeSerializer dateTimeSerializer;

    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    public DateTimeNullableSerializer()

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(DateTimeKind.Utc, BsonType.DateTime);

    }


    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    /// <param name="dateOnly">if set to <c>true</c> [date only].</param>

    public DateTimeNullableSerializer(bool dateOnly)

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(dateOnly);

    }


    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    /// <param name="dateOnly">if set to <c>true</c> [date only].</param>

    /// <param name="representation">The representation.</param>

    public DateTimeNullableSerializer(bool dateOnly, BsonType representation)

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(dateOnly, representation);

    }


    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    /// <param name="representation">The representation.</param>

    public DateTimeNullableSerializer(BsonType representation)

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(DateTimeKind.Utc, representation);

    }


    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    /// <param name="kind">The kind.</param>

    public DateTimeNullableSerializer(DateTimeKind kind)

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(kind, BsonType.DateTime);

    }


    /// <summary>

    /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.

    /// </summary>

    /// <param name="kind">The kind.</param>

    /// <param name="representation">The representation.</param>

    public DateTimeNullableSerializer(DateTimeKind kind, BsonType representation)

    {

        ValueType = typeof(DateTime?);

        dateTimeSerializer = new DateTimeSerializer(kind, representation);

    }


    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)

    {

        if (context.Reader.CurrentBsonType == BsonType.Null)

        {

            context.Reader.ReadNull();

            return null;

        }


        return dateTimeSerializer.Deserialize(context, args);

    }


    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)

    {

        if (value is null)

            context.Writer.WriteNull();

        else

            dateTimeSerializer.Serialize(context, args, (DateTime)value);

    }

}



查看完整回答
反对 回复 2022-06-19
  • 2 回答
  • 0 关注
  • 239 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号