2011-11-15 11 views
6

Digamos que tenemos una clave con valores que son polimórficos en su sentido. Considere el siguiente proyecto de ejemplo:Almacenar un diccionario con valores polimórficos en mongoDB usando C#

public class ToBeSerialized 
{ 
    [BsonId] 
    public ObjectId MongoId; 
    public IDictionary<string, BaseType> Dictionary; 
} 

public abstract class BaseType 
{ 
} 

public class Type1 : BaseType 
{ 
    public string Value1; 
} 

public class Type2:BaseType 
{ 
    public string Value1; 
    public string Value2; 
} 


internal class Program 
{ 
    public static void Main() 
    { 
     var objectToSave = new ToBeSerialized 
           { 
            MongoId = ObjectId.GenerateNewId(), 
            Dictionary = new Dictionary<string, BaseType> 
                { 
                 {"OdEd1", new Type1 {Value1="value1"}}, 
                 { 
                  "OdEd2", 
                  new Type1 {Value1="value1"} 
                  } 
                } 
           }; 
     string connectionString = "mongodb://localhost/Serialization"; 
     var mgsb = new MongoUrlBuilder(connectionString); 
     var MongoServer = MongoDB.Driver.MongoServer.Create(mgsb.ToMongoUrl()); 
     var MongoDatabase = MongoServer.GetDatabase(mgsb.DatabaseName); 
     MongoCollection<ToBeSerialized> mongoCollection = MongoDatabase.GetCollection<ToBeSerialized>("Dictionary"); 
     mongoCollection.Save(objectToSave); 

     ToBeSerialized received = mongoCollection.FindOne(); 
    } 
} 

A veces cuando trato de deserializar, consigo errores deserialización como "valor discriminador Desconocido 'El nombre de tipo inmediato'". ¿Qué estoy haciendo mal? Si cada valor almacena un _t ¿por qué no puede mapearlo correctamente?

Respuesta

9

conductor debe saber acerca de todos los discriminadores deserializar cualquier clase sin errores. Hay dos maneras de hacerlo:

1.Register que a nivel mundial durante el arranque de aplicaciones:

BsonClassMap.RegisterClassMap<Type1>(); 
BsonClassMap.RegisterClassMap<Type2>(); 

2.O aunque el BsonKnownTypes attibute:

[BsonKnownTypes(typeof(Type1), typeof(Type2)] 
public class BaseType 
{ 

} 

Si va a utilizar # 1 o # 2 su deserialización funcionará correctamente.

3

Debe registrar qué tipos heredan de BaseClass antes de intentar deserializarlos. Esto sucederá automáticamente si serializas primero, que es probablemente la razón por la cual el error ocurre solo algunas veces.

Puede registrar los tipos derivados utilizando un atributo:

[BsonDiscriminator(Required = true)] 
[BsonKnownTypes(typeof(DerivedType1), typeof(DerivedType2))] 
public class BaseClass { ... } 

public class DerivedType1 : BaseClass { ... } 
+0

Chicos, gracias. Ahora tengo un dilema cuya respuesta es aceptar –

+2

Bueno, la respuesta de Andrew es más completa. Tengo que admitir que olvidé la sintaxis de la llamada 'BsonClassMap.RegisterClassMap', y cuando la busqué, Andrew ya publicó su respuesta. En general, estoy a favor de la respuesta más completa, porque otros usuarios probablemente echarán un vistazo primero a la respuesta aceptada. – mnemosyn

Cuestiones relacionadas