2011-11-15 5 views
6

Disons que nous avons une clé avec des valeurs qui sont polymorphes dans leur sens. Considérons le prochain projet exemple:Stocker un dictionnaire avec des valeurs polymorphes dans mongoDB en utilisant 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(); 
    } 
} 

Parfois, lorsque je tente de désérialiser, je reçois des erreurs de désérialisation comme « valeur discriminante Unknown 'Le nom du type concret ». Que fais-je de mal? Si chaque valeur stocke un _t pourquoi ne peut-il pas le mapper correctement?

Répondre

9

pilote doit connaître tous les discriminateurs désérialiser une classe sans erreurs. Il y a deux façons de le faire:

1.Register il dans le monde lors du démarrage de l'application:

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

2.Or si le BsonKnownTypes attibute:

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

} 

Si vous utilisez # 1 ou # 2 votre désérialisation fonctionnera correctement.

3

Vous devez enregistrer quels types héritent de BaseClass avant d'essayer de les désérialiser. Cela se produira automatiquement si vous sérialisez en premier, ce qui explique probablement pourquoi l'erreur ne se produit que de temps en temps.

Vous pouvez enregistrer les types dérivés en utilisant un attribut:

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

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

Les gars, merci. Maintenant, j'ai un dilemme dont la réponse à accepter –

+2

Eh bien, la réponse d'Andrew est plus complète. Je dois admettre que j'ai oublié la syntaxe de l'appel 'BsonClassMap.RegisterClassMap', et quand je l'ai cherché, Andrew a déjà posté sa réponse. Je serais généralement favorable à la réponse plus complète, parce que les autres utilisateurs vont probablement jeter un coup d'oeil à la réponse acceptée en premier. – mnemosyn

Questions connexes