但是,如果是查询结果中有时间字段,那这个字段,会被DateTime默认设置为DateTimeKind.Unspecified类型。而这个类型,是无时区信息的,输出显示时,会造成混乱。
为了避免这种情况,在进行时间字段的映射时,需要加上属性:
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]public DateTime post_time { get; set; }
这样做,会强制DateTime类型的字段为DateTimeKind.Local类型。这时候,从显示到使用就正确了。
但是,别高兴的太早,这儿还有一个但是。
这个但是是这样的:数据集中存放的是UTC时间,跟我们正常的时间有8小时时差,如果我们需要按日统计,比方每天的销售额/点击量,怎么搞?上面的方式,解决不了。
当然,基于MongoDB自由的字段处理,可以把需要统计的字段,按年月日时分秒拆开存放,像下面这样的:
class Post_Time{
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
public int hour { get; set; }
public int minute { get; set; }
public int second { get; set; }
}
能解决,但是Low哭了有没有?
下面,终极方案来了。它就是:改写MongoDB中对于DateTime字段的序列化类。当当当~~~
先创建一个类MyDateTimeSerializer:
public class MyDateTimeSerializer : DateTimeSerializer{
public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var obj = base.Deserialize(context, args);
return new DateTime(obj.Ticks, DateTimeKind.Unspecified);
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
{
var utcValue = new DateTime(value.Ticks, DateTimeKind.Utc);
base.Serialize(context, args, utcValue);
}
}
代码简单,一看就懂。
注意,使用这个方法,上边那个对于时间加的属性[BsonDateTimeOptions(Kind = DateTimeKind.Local)]一定不要添加,要不然就等着哭吧:P
创建完了,怎么用?
如果你只想对某个特定映射的特定字段使用,比方只对CollectionModel的post_time字段来使用,可以这么写:
[BsonSerializer(typeof(MyDateTimeSerializer))]public DateTime post_time { get; set; }
或者全局使用:
BsonSerializer.RegisterSerializer(typeof(DateTime), new MongoDBDateTimeSerializer());BsonSerializer是MongoDB.Driver的全局对象。所以这个代码,可以放到使用数据库前的任何地方。例如在Demo中,我放在Main里了:
static async Task Main(string[] args){
BsonSerializer.RegisterSerializer(typeof(DateTime), new MyDateTimeSerializer());
await Demo();
Console.ReadKey();
}
这回看数据,数据集中的post_time跟当前时间显示完全一样了,你统计,你分组,可以随便霍霍了。
7. Dictionary字段这个需求很奇怪。我们希望在一个Key-Value的文档中,保存一个Key-Value的数据。但这个需求又是真实存在的,比方保存一个用户的标签和标签对应的命中次数。
数据声明很简单:
public Dictionary<string, int> extra_info { get; set; }MongoDB定义了三种保存属性:Document、ArrayOfDocuments、ArrayOfArrays,默认是Document。