2011-08-07 11 views
6

Tengo problemas al intentar agregar tipos complejos a documentos existentes en Mongo.Agregar clases complejas a Mongo

Tengo las siguientes dos clases.

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; } 
} 

continuación, se crea un nuevo objeto para la inserción.

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

Inserte el documento.

mongoCollection.Insert(bd.ToBsonDocument()); 

Y obtengo el documento resultante.

{ "_id": BinData (3, "t089M1E1j0OFVS3YVuEDwg =="), "UserObjects": { "datos": 12, "data2": 123, "Data3": { "_T": "ComplexClass" , "Barra": "barra", "Foo": 1234} }}

El documento se inserta correctamente. Luego modifico uno de los valores.

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); 

El documento tal como aparece en la base de datos.

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

Si intento recuperar este registro, obtengo una excepción FileFormatException .

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

(Excepción no controlada: System.IO.FileFormatException: No se puede determinar t real ipo de objeto deserializar NominalType es System.Object y BsonType es Docum ent..).

A diferencia de data3, data2 no tiene un discriminador. ¿Qué estoy haciendo?

Respuesta

4

bien, si el conductor quiere discriminador le puede dar por la emisión de su clase para oponerse En la actualización:

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

Esto va a resolver su problema.

Por cierto, su actualización no actualizar realmente campo datos2 dentro UserObjects, es la creación de nuevo campo datos2 dentro del documento, siguiente código debería funcionar correctamente:

Update.SetWrapped<ComplexClass>("UserObjects.data2", 
         new ComplexClass() { Foo = -1234, Bar = "FooBar" }), 
2

El deserializador no puede determinar cuál es el tipo de letra que se debe usar según la representación de Bson. Echa un vistazo a mi pregunta hace unos días. Creo que aclara algunas cosas. La implementación de BsonSerializable resolvería el problema.

Storing composite/nested object graph

Cuestiones relacionadas