1

DateTimeフィールドがあり、MongoDBコレクションから読み取り、そのクラスに逆シリアル化しています。DateTime DBフィールドにnullがあり、MongoDriverがnull許容型ではないそのdatetimeフィールドにnullを設定しようとしている場合を考えてみましょう。スローエラーです。

.FindAll()。ToList()=>ここでエラー。

この問題を克服するための助けはありますか?

注:null許容のDatetime(DateTime?)を使用できます。ただし、ドメインモデルでのみnull許容型が必要です。だから私はシリアル化中にnull許容でないDateTimeを使用したいだけです

4

1 に答える 1

2

この場合、 2つの可能性がありますnullnullあなたはあなたのデータベースに実際を保存することができたでしょう:

{
    _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);
        }
    }
}

(この場合、anullがシリアル化または逆シリアル化されるたびに現在の日付を指定します)

次に、これをDateTimeタイプのシリアライザーとして登録する必要があります。

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

そもそもデータがないように、ソースでデータをサニタイズする方が簡単だと言わなければなりませんnulls


2番目のケースでは、これは1.5以降のMongoDBのC#ドライバーによって処理されていますが、どのバージョンを使用していますか?次のように独自のクラスマップを登録することでデフォルト値を設定できますが、前述のように、これは不要になります。

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