MongoDB 10Gen驱动程序空值处理

时间:2012-09-13 06:00:21

标签: mongodb mongodb-.net-driver

我们正在使用DateTime字段,我们正在从MongoDB集合中读取并反序列化到该类中。让我们说如果它在DateTime DB字段中为null,并且MongoDriver试图将null设置为不可为空的类型的datetime字段。这是投掷错误。

.FindAll()。ToList()=>错误在这里。

有任何帮助来克服这个问题吗?

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

1 个答案:

答案 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());
});