目录
介绍
背景
使用代码
兴趣点
目前不支持将DateTimeOffset序列化为MongoDB中的DateTime。该解决方案将向您展示它是如何工作的。
介绍
如果您需要DateTimeOffsets在模型中使用,并且希望将其存储为BsonType DateTime,则会出现“ 'DateTime' is not a valid DateTimeOffset representation.”或“ Cannot deserialize a 'DateTimeOffset' from BsonType 'DateTime'.” 等错误
背景
我们在某些模型中使用DateTimeOffsets,因为我们有一个基于XML的导入运行,其值包含DateTimeOffsets(XXXXXX +01:00)或类似值。虽然我们希望这些值能作为DateTime被储存在MongoDB中。我们不太关心偏移信息,存储的UTC对我们来说很好。
您可以轻松在MongoDB中创建自己的DateTimeOffset序列化器并将其注册为DateTimeOffset序列化器。我会告诉你如何处理。
使用代码
您可以查看MongoDB C#客户端的源代码,看看如何构建DateTimeSerializer或DateTimeOffset序列化器,并调整其中的内容。最终的序列化程序可能如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96public class DateTimeOffsetSupportingBsonDateTimeSerializer : StructSerializerBase<DateTimeOffset>, IRepresentationConfigurable<DateTimeOffsetSupportingBsonDateTimeSerializer> { private BsonType _representation; private string StringSerializationFormat = "YYYY-MM-ddTHH:mm:ss.FFFFFFK"; public DateTimeOffsetSupportingBsonDateTimeSerializer() : this(BsonType.DateTime) { } public DateTimeOffsetSupportingBsonDateTimeSerializer(BsonType representation) { switch (representation) { case BsonType.String: case BsonType.DateTime: break; default: throw new ArgumentException(string.Format("{0} is not a valid representation for {1}", representation, this.GetType().Name)); } _representation = representation; } public BsonType Representation => _representation; public override DateTimeOffset Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var bsonReader = context.Reader; long ticks; TimeSpan offset; BsonType bsonType = bsonReader.GetCurrentBsonType(); switch (bsonType) { case BsonType.String: var stringValue = bsonReader.ReadString(); return DateTimeOffset.ParseExact (stringValue, StringSerializationFormat, DateTimeFormatInfo.InvariantInfo); case BsonType.DateTime: var dateTimeValue = bsonReader.ReadDateTime(); return DateTimeOffset.FromUnixTimeMilliseconds(dateTimeValue); default: throw CreateCannotDeserializeFromBsonTypeException(bsonType); } } public override void Serialize (BsonSerializationContext context, BsonSerializationArgs args, DateTimeOffset value) { var bsonWriter = context.Writer; switch (_representation) { case BsonType.String: bsonWriter.WriteString(value.ToString (StringSerializationFormat, DateTimeFormatInfo.InvariantInfo)); break; case BsonType.DateTime: bsonWriter.WriteDateTime(value.ToUnixTimeMilliseconds()); break; default: var message = string.Format("'{0}' is not a valid DateTimeOffset representation.", _representation); throw new BsonSerializationException(message); } } public DateTimeOffsetSupportingBsonDateTimeSerializer WithRepresentation(BsonType representation) { if(representation == _representation) { return this; } return new DateTimeOffsetSupportingBsonDateTimeSerializer(representation); } IBsonSerializer IRepresentationConfigurable.WithRepresentation(BsonType representation) { return WithRepresentation(representation); } protected Exception CreateCannotDeserializeFromBsonTypeException(BsonType bsonType) { var message = string.Format("Cannot deserialize a '{0}' from BsonType '{1}'.", BsonUtils.GetFriendlyTypeName(ValueType), bsonType); return new FormatException(message); } }
生成的序列化程序可以处理DateTimeOffsets从/到strings和DateTimes(您也可以省略string表示部分)的序列化。您可以在顶部添加您感兴趣的任何逻辑。要注册新的序列化程序,您应该在开始使用MongoCollection之前调用以下内容。
1BsonSerializer.RegisterSerializer<DateTimeOffset>(new DateTimeOffsetSupportingBsonDateTimeSerializer());
你准备好了。
兴趣点
DateTimes时间在MongoDb中表示为自unix纪元以来的毫秒数。.NET框架现在内置了使用这些值从和到DateTimeOffset进行转换的支持
因此,无论您的DateTimeOffset值是“2018-11-24T14:40:23+05:00”还是“2018-11-24T09:40:23+00:00”,它都会在MongoDB中生成相同的DateTime。
原文地址:https://www.codeproject.com/Tips/1268086/MongoDB-Csharp-Serializer-for-DateTimeOffset-to-Bs
最后
以上就是年轻世界最近收集整理的关于MongoDB C#:DateTimeOffset到BsonType DateTime的序列化程序介绍背景使用代码兴趣点的全部内容,更多相关MongoDB内容请搜索靠谱客的其他文章。
发表评论 取消回复