2012-03-20 30 views
8

Tôi mới đến MongoDB, và đang cố gắng để có được trình điều khiển C# để làm việc serializing F # lớp học. Tôi có nó làm việc với lớp tự động bằng cách sử dụng các trường F # có thể thay đổi được & một hàm tạo tham số, nhưng thực sự tôi cần giữ lại tính bất biến, vì vậy tôi bắt đầu xem xét việc triển khai IBsonSerializer để thực hiện tuần tự hóa tùy chỉnh. Tôi đã không tìm thấy bất kỳ tài liệu hướng dẫn để viết một trong những vì vậy đã chỉ cố gắng suy ra từ mã nguồn trình điều khiển.MongoDB tùy chỉnh serializer thực hiện

Tôi đã gặp sự cố trong đó khi phương pháp Deserialize được gọi trên bộ nối tiếp, CurrentBsonType được đặt thành EndOfDocument thay vì bắt đầu như tôi mong đợi. Tôi đã viết tương đương trong C# chỉ để chắc chắn rằng nó không phải là một số F # weirdness, nhưng vấn đề vẫn tồn tại. Phần tuần tự hóa dường như hoạt động tốt và có thể truy vấn được từ trình bao. Đây là mã mẫu:

class Calendar { 
    public string Id { get; private set; } 
    public DateTime[] Holidays { get; private set; } 

    public Calendar(string id, DateTime[] holidays) { 
     Id = id; 
     Holidays = holidays; 
    } 
} 

class CalendarSerializer : BsonBaseSerializer { 
    public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { 
     var calendar = (Calendar) value; 
     bsonWriter.WriteStartDocument(); 
     bsonWriter.WriteString("_id", calendar.Id); 
     bsonWriter.WriteName("holidays"); 
     var ser = new ArraySerializer<DateTime>(); 
     ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null); 
     bsonWriter.WriteEndDocument(); 
    } 

    public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { 
     if (nominalType != typeof(Calendar) || actualType != typeof(Calendar)) 
      throw new BsonSerializationException(); 

     if (bsonReader.CurrentBsonType != BsonType.Document) 
      throw new FileFormatException(); 

     bsonReader.ReadStartDocument(); 
     var id = bsonReader.ReadString("_id"); 
     var ser = new ArraySerializer<DateTime>(); 
     var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null); 
     bsonReader.ReadEndDocument(); 
     return new Calendar(id, holidays); 
    } 

    public override bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) { 
     var calendar = (Calendar) document; 
     id = calendar.Id; 
     idNominalType = typeof (string); 
     idGenerator = new StringObjectIdGenerator(); 
     return true; 
    } 

    public override void SetDocumentId(object document, object id) { 
     throw new NotImplementedException("SetDocumentId is not implemented"); 
    } 
} 

Điều này thổi lên với FileFormatException trong Deserialize khi CurrentBsonType không phải là tài liệu. Tôi đang sử dụng phiên bản 1.4 mới nhất của tài nguyên trình điều khiển.

Trả lời

7

Tôi đã tìm ra điều này cuối cùng. Tôi đã sử dụng bsonReader.GetCurrentBsonType() thay vì bsonReader.CurrentBsonType. Điều này đọc BsonType trong bộ đệm thay vì chỉ nhìn vào điều cuối cùng ở đó. Tôi cũng đã sửa một lỗi derserializing tiếp theo. Phương thức được cập nhật trông giống như sau:

public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { 
    if (nominalType != typeof(Calendar) || actualType != typeof(Calendar)) 
     throw new BsonSerializationException(); 

    if (bsonReader.GetCurrentBsonType() != BsonType.Document) 
     throw new FileFormatException(); 

    bsonReader.ReadStartDocument(); 
    var id = bsonReader.ReadString("_id"); 
    bsonReader.ReadName(); 
    var ser = new ArraySerializer<DateTime>(); 
    var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null); 
    bsonReader.ReadEndDocument(); 
    return new Calendar(id, holidays); 
} 
Các vấn đề liên quan