2011-11-15 37 views
6

Hãy để chúng tôi nói rằng chúng tôi có một chìa khóa với các giá trị có tính đa hình theo ý nghĩa của chúng. Hãy xem xét các dự án mẫu tiếp theo:Lưu trữ một từ điển với các giá trị đa hình trong mongoDB sử dụng 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(); 
    } 
} 

Đôi khi tôi cố gắng deserialize nó, tôi nhận được lỗi deserialization như "giá trị phân biệt Unknown 'Tên của loại bê tông". Tôi đang làm gì sai? Nếu mọi giá trị lưu trữ _t tại sao nó không thể ánh xạ chính xác giá trị đó?

Trả lời

9

điều khiển nên biết về tất cả discriminators để deserialize bất kỳ lớp mà không có lỗi. Có hai cách để làm điều đó:

1.Register nó trên toàn cầu trong quá trình khởi ứng dụng:

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

2.Or dù BsonKnownTypes attibute:

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

} 

Nếu bạn sẽ sử dụng # 1 hoặC# 2 deserialization của bạn sẽ hoạt động chính xác.

3

Bạn phải đăng ký loại được kế thừa từ BaseClass trước khi cố gắng deserialize chúng. Điều này sẽ xảy ra tự động nếu bạn tuần tự hóa đầu tiên, đó có thể là lý do tại sao lỗi chỉ xảy ra đôi khi.

Bạn có thể đăng ký các loại có nguồn gốc sử dụng một thuộc tính:

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

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

Các bạn, cảm ơn. Bây giờ tôi có một tiến thoái lưỡng nan có câu trả lời để chấp nhận –

+2

Vâng, câu trả lời của Andrew là hoàn chỉnh hơn. Tôi phải thừa nhận rằng tôi đã quên cú pháp của cuộc gọi 'BsonClassMap.RegisterClassMap', và khi tôi đã tra cứu nó, Andrew đã đăng câu trả lời của mình. Tôi thường ủng hộ câu trả lời hoàn chỉnh hơn, bởi vì những người dùng khác có thể sẽ xem xét câu trả lời được chấp nhận trước. – mnemosyn

Các vấn đề liên quan