2011-11-15 11 views
6

Powiedzmy, że mamy klucz z wartościami, które są polimorficzne w ich rozumieniu. Rozważmy kolejny przykładowy projekt:Przechowywanie Słownika z wartościami polimorficznymi w mongoDB za pomocą 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(); 
    } 
} 

Czasem gdy próbuję go deserializowania, otrzymuję błędy deserializacjia jak „nieznanej wartości dyskryminatora«Nazwa betonowych typu»”. Co robię źle? Jeśli każda wartość przechowuje _t ​​dlaczego nie można go poprawnie odwzorować?

Odpowiedz

9

kierowca powinien wiedzieć o wszystkich Dyskryminatory deserializacji dowolną klasę bez błędów. Istnieją dwa sposoby, aby to zrobić:

1.Register nim globalnie podczas startu aplikacji:

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

2.Or choć BsonKnownTypes attibute:

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

} 

Jeśli będziesz używać # 1 lub # 2 deserializacja będzie działać poprawnie.

3

Musisz się zarejestrować, które typy dziedziczą po BaseClass przed próbą deserializacji. Nastąpi to automatycznie, jeśli najpierw serializuje się, co prawdopodobnie powoduje, że błąd występuje tylko czasami.

Można zarejestrować typów pochodnych za pomocą atrybutu:

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

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

Faceci, dziękuję. Teraz mam dylemat, którego odpowiedź na akceptację –

+2

Cóż, odpowiedź Andrew jest bardziej kompletna. Muszę przyznać, że zapomniałem o składni wywołania 'BsonClassMap.RegisterClassMap', a kiedy już to sprawdziłem, Andrew już opublikował swoją odpowiedź. Ogólnie rzecz biorąc, wolę bardziej kompletną odpowiedź, ponieważ inni użytkownicy prawdopodobnie najpierw przyjrzą się zaakceptowanej odpowiedzi. – mnemosyn

Powiązane problemy