How to make Update.Set honor my DateTime serialization options?
I am using the official 10gen C# driver for mongoDB. I have some code that sets up BSON mappings, it's ran once on application start:
BsonClassMap.RegisterClassMap<Review>(cm =>
{
cm.AutoMap();
cm.MapProperty(c => c.Date)
.SetSerializationOptions(new DateTimeSerializationOptions{DateOnly = true});
cm.UnmapProperty(c => c.Author);
});
This works fi开发者_如何学Pythonne when a Review is an embedded document and gets saved with its parent. However now I am trying to update a particular review and it involves some manual coding like so (magic strings, ugh):
collection.Update(query,
Update.Set("Reviews.$.Date", review.Date)
.Set("Reviews.$.Rating", review.Rating)
.Set("Reviews.$.Title", review.Title)
.Set("Reviews.$.Comment", review.Comment)
);
This also works... But it doesn't honor the serialization settings for DateTime on the Review class and apparently saves the time part as well (even though it'd be midnight, since review.Date == DateTime.Today
). Then when I try to retrieve that document I get an exception: [FileFormatException: TimeOfDay component for DateOnly DateTime value is not zero]
.
How do I fix this?
Wow. This is a tough one. I'll have to think some how to best solve this. Bryan's answer is correct that the serialization options are only used when you are serializing the whole class. But his last suggestion to call RegisterClassMap on DateTime is not right.
But I can offer you a workaround. The reason you are getting the exception is that the DateTime you are using might be midnight in your local timezone, but it is being converted to UTC to store in the database. That's where the non-zero time component is coming from.
You can suppress the conversion to UTC by using:
.Set("Reviews.$.Date", DateTime.SpecifyKind(review.Date, DateTimeKind.Utc))
This should work, but let me know if it doesn't and I'll investigate further.
I think the way the serializer works is that it only uses your mappings when serializing the entire class. You are not serializing the Review
class, but are instead serializing the Date
property of the Review
class.
Maybe you should try to register a mapping for the DateTime
class:
BsonClassMap.RegisterClassMap<DateTime>(...);
Dont know if this will work because I have not had the chance to test it yet, but give it a shot.
精彩评论