使用MongoDB的都知道MongoDB存储时间类型存在时区问题
1、简单处理方法:
把日期类型改为字符串存储
2、对实体类的读写方法进行逻辑处理(要定义时区标识并自定义读写方法)
3、利用MongoDB.Bson的序列化实现(我的处理方案)
DateTime类型:
public class MongoDateTimeSerializer : IBsonSerializer<DateTime>
{
public Type ValueType => typeof(DateTime);
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var bsonType = context.Reader.CurrentBsonType;
if (bsonType == BsonType.DateTime)
{
return new DateTime(1970, 1, 1).AddMilliseconds(context.Reader.ReadDateTime());
}
else {
throw new Exception("类型错误");
}
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
if (value != null)
{
context.Writer.WriteDateTime(Convert.ToInt64((Convert.ToDateTime(value) - new DateTime(1970, 1, 1)).TotalMilliseconds));
}
else
{
context.Writer.WriteNull();
}
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
{
context.Writer.WriteDateTime(Convert.ToInt64((value - new DateTime(1970, 1, 1)).TotalMilliseconds));
}
DateTime IBsonSerializer<DateTime>.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var bsonType = context.Reader.CurrentBsonType;
if (bsonType == BsonType.DateTime)
{
return new DateTime(1970, 1, 1).AddMilliseconds(context.Reader.ReadDateTime());
}
else
{
throw new Exception("类型错误");
}
}
}
DateTime?类型:
public class MongoNullDateTimeSerializer : IBsonSerializer<DateTime?>
{
public Type ValueType => typeof(DateTime?);
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var bsonType = context.Reader.CurrentBsonType;
if (bsonType == BsonType.DateTime)
{
return new DateTime(1970, 1, 1).AddMilliseconds(context.Reader.ReadDateTime());
}
else if (bsonType == BsonType.Null)
{
context.Reader.ReadNull();
return null;
}
else
{
throw new Exception("类型错误");
}
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
if (value != null)
{
context.Writer.WriteDateTime(Convert.ToInt64((Convert.ToDateTime(value) - new DateTime(1970, 1, 1)).TotalMilliseconds));
}
else
{
context.Writer.WriteNull();
}
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime? value)
{
if (value != null)
{
context.Writer.WriteDateTime(Convert.ToInt64((value.Value - new DateTime(1970, 1, 1)).TotalMilliseconds));
}
else
{
context.Writer.WriteNull();
}
}
DateTime? IBsonSerializer<DateTime?>.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var bsonType = context.Reader.CurrentBsonType;
if (bsonType == BsonType.DateTime)
{
return new DateTime(1970, 1, 1).AddMilliseconds(context.Reader.ReadDateTime());
}
else if (bsonType == BsonType.Null)
{
context.Reader.ReadNull();
return null;
}
else
{
throw new Exception("类型错误");
}
}
}
项目启动时注册类型的序列化实现
public override void ConfigureServices(ServiceConfigurationContext context)
{
BsonSerializer.RegisterSerializer(typeof(DateTime), new MongoDateTimeSerializer() );
BsonSerializer.RegisterSerializer(typeof(DateTime?), new MongoNullDateTimeSerializer());
}