1

我们有 DateTime 字段,我们正在从 MongoDB 集合中读取并反序列化到该类中。假设它在 DateTime DB 字段中是否有 null 并且 MongoDriver 正在尝试将 null 设置为不可为 null 类型的 datetime 字段。它抛出错误。

.FindAll().ToList() => 此处出错。

有什么帮助可以克服这个问题吗?

请注意:我们可以使用可为空的 Datetime (DateTime?) 。但我们只在域模型中需要不可为空的类型。所以我只想在序列化时使用不可为空的 DateTime

4

1 回答 1

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(在这种情况下,只要 a被序列化或反序列化,就给出当前日期)

然后,您需要将其注册为 DateTime 类型的序列化程序:

BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
    cm.AutoMap();
    cm.GetMemberMap(mc => mc.MyDateTime).SetSerializer(new DateTimeSerializer());
});

不得不说,在源头对数据进行清理会更容易,因此它一开始就没有nulls


在第二种情况下,这已由 MongoDB 的 C# 驱动程序从1.5开始处理,您使用的是哪个版本?您可以通过注册自己的类映射来设置默认值,如下所示,但如上所述,不再需要它。

BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
   cm.AutoMap();
   cm.GetMemberMap(mc => mc.MyDateTime).SetDefaultValue(new DateTime());
});
于 2012-09-14T06:53:53.473 回答