我正在使用mongoDB的官方10gen C#驱动程序。我有一些设置BSON映射的代码,它在应用程序启动时运行一次:
BsonClassMap.RegisterClassMap<Review>(cm =>
{
cm.AutoMap();
cm.MapProperty(c => c.Date)
.SetSerializationOptions(new DateTimeSerializationOptions{DateOnly = true});
cm.UnmapProperty(c => c.Author);
});
当Review是嵌入式文档并使用其父级保存时,这可以正常工作。但是现在我正在尝试更新一个特定的评论,它涉及一些像这样的手动编码(魔术字符串,呃):
collection.Update(query,
Update.Set("Reviews.$.Date", review.Date)
.Set("Reviews.$.Rating", review.Rating)
.Set("Reviews.$.Title", review.Title)
.Set("Reviews.$.Comment", review.Comment)
);
这也有效......但是它不遵守Review类上DateTime的序列化设置,并且显然也保存了时间部分(即使它是午夜,因为review.Date == DateTime.Today
)。然后当我尝试检索该文档时,我得到一个例外:[FileFormatException: TimeOfDay component for DateOnly DateTime value is not zero]
。
我该如何解决这个问题?
答案 0 :(得分:3)
哇。这是困难的一个。我将不得不考虑如何最好地解决这个问题。 Bryan的答案是正确的,序列化选项仅在序列化整个类时使用。但他最后一个在DateTime上调用RegisterClassMap的建议是不对的。
但我可以为你提供一个解决方法。您获得异常的原因是您使用的DateTime可能是本地时区的午夜,但它正在转换为UTC以存储在数据库中。这就是非零时间组件的来源。
您可以使用以下方法禁止转换为UTC:
.Set(“Reviews。$。Date”,DateTime.SpecifyKind(review.Date,DateTimeKind.Utc))
这应该有效,但如果没有,请告诉我,我会进一步调查。
答案 1 :(得分:0)
我认为序列化程序的工作方式是它只在序列化整个类时使用映射。您没有序列化Review
类,而是序列化Date
类的Review
属性。
也许你应该尝试为DateTime
类注册一个映射:
BsonClassMap.RegisterClassMap<DateTime>(...);
不知道这是否有效,因为我还没有机会测试它,但是试一试。