gpt4 book ai didi

c# - NodaTime with MongoDB : Value class NodaTime. ZonedDateTime 无法反序列化

转载 作者:可可西里 更新时间:2023-11-01 09:11:43 25 4
gpt4 key购买 nike

我使用的是最新版本的 NodaTimeMongo DB Official Driver .我有一个简单的 POCO 类,它使用 NodaTime 的 ZonedDateTime作为一些属性中 .NET DateTime 的替代品。

public class MyPOCO
{
[BsonId]
[Key]
public ObjectId SomeId { get; set; }

public string SomeProperty { get; set; }

public ZonedDateTime SomeDateTime { get; set; }
}

我可以轻松地将模型放入集合中,但是当我尝试读取查询的模型时,我得到以下信息 MongoDB.Bson.BsonSerializationException :

Value class NodaTime.ZonedDateTime cannot be deserialized

解决/变通此问题的好的做法或最佳做法是什么?

更新

在发布我的 solution 之后对于这个问题,我面临着一个可能的新问题......当我查询集合并在查询中使用 DateTime 时,例如 where SomeDateTime < now' (where现在is a variable I create from system time) it seems that each document must be deserialized using my可以评估 where 子句之前的 ZonedDateTimeSerializer`。这看起来像是一个很大的性能问题,不是吗?我真的不得不考虑再次回到 BCL DateTime,即使这很痛苦。

更新 2

我接受使用 ZonedDateTimeSerializer 的解决方案,但我对 NodaTime 与 MongoDB 的结合感到不舒服,虽然两者都是很好的独立解决方案。但如果不进行大量操作,它们目前不能很好地协同工作。

最佳答案

没关系,经过大量阅读和试验,终于找到了。我编写了一个自定义 BsonBaseSerializer 实现来处理 ZonedDateTime

这是我的 ZonedDateTimeSerializer 的代码:

/// <summary>
/// Serializer for the Noda
/// </summary>
public class ZonedDateTimeSerializer : BsonBaseSerializer
{
private static ZonedDateTimeSerializer __instance = new ZonedDateTimeSerializer();

/// <summary>
/// Initializes a new instance of the ZonedDateTimeSerializer class.
/// </summary>
public ZonedDateTimeSerializer()
{
}

/// <summary>
/// Gets an instance of the ZonedDateTimeSerializer class.
/// </summary>
public static ZonedDateTimeSerializer Instance
{
get { return __instance; }
}

/// <summary>
/// Deserializes an object from a BsonReader.
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>
/// An object.
/// </returns>
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
VerifyTypes(nominalType, actualType, typeof(ZonedDateTime));

var bsonType = bsonReader.GetCurrentBsonType();
if (bsonType == BsonType.DateTime)
{
var millisecondsSinceEpoch = bsonReader.ReadDateTime();
return new Instant(millisecondsSinceEpoch).InUtc();
}

throw new InvalidOperationException(string.Format("Cannot deserialize ZonedDateTime from BsonType {0}.", bsonType));
}

/// <summary>
/// Serializes an object to a BsonWriter.
/// </summary>
/// <param name="bsonWriter">The BsonWriter.</param>
/// <param name="nominalType">The nominal type.</param>
/// <param name="value">The object.</param>
/// <param name="options">The serialization options.</param>
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
if (value == null)
throw new ArgumentNullException("value");

var ZonedDateTime = (ZonedDateTime)value;
bsonWriter.WriteDateTime(ZonedDateTime.ToInstant().Ticks);
}
}

不要忘记注册序列化程序。我无法找到如何按类型注册序列化程序,但您可以按类型注册它,如下所示:

BsonClassMap.RegisterClassMap<MyPOCO>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(a => a.SomeDateTime).SetSerializer(ZonedDateTimeSerializer.Instance);
});

希望这对您有所帮助。

关于c# - NodaTime with MongoDB : Value class NodaTime. ZonedDateTime 无法反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17882795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com