2011-11-15 19 views
6

Diciamo che abbiamo una chiave con valori che sono polimorfici nel loro senso. Prendere in considerazione il progetto di esempio seguente:Memorizzare un dizionario con valori polimorfici in 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 volte, quando si tenta di deserializzare, ottengo gli errori di deserializzazione come "valore discriminatore Unknown 'Il nome di tipo concreto'". Cosa sto sbagliando? Se ogni valore memorizza un _t perché non può mapparlo correttamente?

risposta

9

conducente dovrebbe conoscere tutti i discriminatori per deserializzare qualsiasi classe senza errori. Ci sono due modi per farlo:

1.Register globalmente durante l'avvio app:

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

2.Or se il BsonKnownTypes attibute:

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

} 

Se si utilizza 1 o # # 2 la tua deserializzazione funzionerà correttamente.

3

È necessario registrare quali tipi ereditano da BaseClass prima di tentare di deserializzarli. Ciò avverrà automaticamente se si serializza per primo, il che probabilmente è il motivo per cui l'errore si verifica solo qualche volta.

È possibile registrare tipi derivati ​​utilizzando un attributo:

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

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

Ragazzi, grazie. Ora ho un dilemma la cui risposta ad accettare –

+2

Bene, la risposta di Andrew è più completa. Devo ammettere che ho dimenticato la sintassi della chiamata 'BsonClassMap.RegisterClassMap', e quando l'ho cercato, Andrew ha già postato la sua risposta. Preferirei in generale la risposta più completa, perché gli altri utenti probabilmente daranno un'occhiata prima alla risposta accettata. – mnemosyn

Problemi correlati