thm*_*shd 4 c# mongodb nodatime mongodb-.net-driver
我正在使用最新版本的NodaTime和Mongo DB官方驱动程序.我有一个简单的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; }
}
Run Code Online (Sandbox Code Playgroud)
我可以轻松地将Model放入集合中,但是当我尝试读取查询的模型时,我得到以下内容MongoDB.Bson.BsonSerializationException:
值类NodaTime.ZonedDateTime无法反序列化
什么是解决/解决这个问题的好或最佳做法?
UPDATE
在发布我的问题解决方案后,我面临一个可能的新问题......当我查询集合并在我的查询中使用DateTime时,就像where SomeDateTime < now' (where现在is a variable I create from system time) it seems that each document must be deserialized using myZonedDateTimeSerializer`可以在where子句之前进行评估.这看起来像是一个很大的性能问题,不是吗?我真的要考虑再次回到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);
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记注册Serializer.我无法找到如何为每种类型注册Serializer,但您可以按类型注册它,如下所示:
BsonClassMap.RegisterClassMap<MyPOCO>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(a => a.SomeDateTime).SetSerializer(ZonedDateTimeSerializer.Instance);
});
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
1243 次 |
| 最近记录: |