Добавление сложных классов в Mongo - PullRequest
6 голосов
/ 07 августа 2011

У меня проблемы при попытке добавить сложные типы в существующие документы в Mongo.

У меня есть два следующих класса.

public class UserObjectCollection {

    [BsonId]
    public Guid UserId { get; set; }

    public Dictionary<string, object> UserObjects { get; set; }

    public UserObjectCollection() {
        UserObjects = new Dictionary<string, object>();
    }
}

public class ComplexClass {
    public string Bar { get; set; }
    public int Foo { get; set; }
}

Затем я создаю новый объект для вставки.

var bd = new UserObjectCollection() {
    UserId = Guid.NewGuid(),
    UserObjects = {
        { "data", 12 },
        { "data2", 123 },
        { "data3", new ComplexClass() { Bar= "bar", Foo=1234 } }
    }
};

Вставьте документ.

mongoCollection.Insert(bd.ToBsonDocument());

И я получу полученный документ.

{"_id": BinData (3, "t089M1E1j0OFVS3YVuEDwg =="), "UserObjects": {"data": 12, "data2": 123, "data3": {"_t": "ComplexClass", "Bar": "bar", "Foo": 1234}}}

Документ вставлен правильно.Затем я изменяю одно из значений.

var query = Query.EQ("UserObjects.data", BsonValue.Create(12));

collection.FindAndModify(
  query, 
  SortBy.Null, 
  Update.SetWrapped<ComplexClass>("data2", new ComplexClass() { Foo = -1234, Bar = "FooBar" }),
  returnNew: false, 
  upsert: true);

Документ, который отображается в базе данных.

{"UserObjects": {"data": 12, "data2": {"Bar ":" FooBar "," Foo ": -1234}," data3 ": {" _t ":" ComplexClass "," Bar ":" bar "," Foo ": 1234}}," _id ": BinData (3, "W11Jy + hYqE2nVfrBdxn54g ==")}

Если я пытаюсь извлечь эту запись, я получаю исключение FileFormatException.

var theDocument = collection.Find(query).First();

(необработанное исключение: System.IO.FileFormatException: невозможночтобы определить фактический тип объекта для десериализации. NominalType - это System.Object, а BsonType - это Docum ent.).

В отличие от data3, data2 не имеет дискриминатора.Что я делаю?

Ответы [ 2 ]

4 голосов
/ 22 августа 2011

Хорошо, если драйвер хочет дискриминатор, вы можете передать его, приведя ваш класс к объекту в обновлении:

(object)(new ComplexClass() { Foo = -1234, Bar = "FooBar" })

Это решит вашу проблему.

Кстати, ваше обновление фактически не обновляетсяполе data2 в UserObjects, оно создает новое поле data2 в документе, следующий код должен работать правильно:

 Update.SetWrapped<ComplexClass>("UserObjects.data2", 
                       new ComplexClass() { Foo = -1234, Bar = "FooBar" }),
2 голосов
/ 22 августа 2011

Десериализатор не может самостоятельно определить, какой тип он должен использовать, основываясь на представлении Bson.Посмотрите на мой вопрос несколько дней назад.Я думаю, что это проясняет несколько вещей.Внедрение BsonSerializable решит проблему.

Сохранение графа составного / вложенного объекта

...