我们正在使用DateTime字段,我们正在从MongoDB集合中读取并反序列化到该类中。让我们说如果它在DateTime DB字段中为null,并且MongoDriver试图将null设置为不可为空的类型的datetime字段。这是投掷错误。
.FindAll()。ToList()=>错误在这里。
有任何帮助来克服这个问题吗?
请注意:我们可以使用可空的Datetime(DateTime?)。但我们只需要在域模型中使用非可空类型。所以我只想在序列化时使用不可为空的DateTime
答案 0 :(得分:2)
在这种情况下null
有两种可能性。您可以在数据库中存储实际的null
:
{
_id:ObjectId(),
MyDateTime:null
}
或者您根本不存储该字段:
{
_id:ObjectId()
}
在第一种情况下,您可以通过创建自己的序列化程序来处理此问题:
public class DateTimeSerializer : BsonBaseSerializer
{
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType)
{
case BsonType.Null:
bsonReader.ReadNull();
return new DateTime();
case BsonType.DateTime:
return bsonReader.ReadDateTime();
default:
var message = string.Format("DateTimeSerializer needs a DateTime not {0}.", bsonType);
throw new BsonSerializationException(message);
}
}
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
if (value == null)
{
TimeSpan nowMs = DateTime.Now-new DateTime(1970,1,1);
bsonWriter.WriteDateTime((long)nowMs.TotalMilliseconds);
}
else
{
bsonWriter.WriteString((string)value);
}
}
}
(在这种情况下,每当null
被序列化或反序列化时给出当前日期
然后,您需要将其注册为DateTime类型的序列化程序:
BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(mc => mc.MyDateTime).SetSerializer(new DateTimeSerializer());
});
必须要说的是,在源头处清理数据会更容易,因此它首先没有nulls
。
在第二种情况下,这是由1.5以来的MongoDB的C#驱动程序处理的,您使用的是哪个版本?您可以通过注册自己的类映射来设置默认值,如下所示,但如上所述,不再需要它。
BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(mc => mc.MyDateTime).SetDefaultValue(new DateTime());
});