2017-06-01 116 views
0

我有一個A類和B類和CBsonSerializer.Deserialize <T>(bsonDocument) - 子對象的Id字段導致異常

public class A 
{ 
    public string Id {get;set;} 
    public List<B> Children {get;set;} 
} 
public class B 
{ 
    public string Id {get;set;} 
    public string Foo {get;set;} 
    public double Bar {get;set;} 
} 
public class C 
{ 
    public string Id {get;set;} 
    //This property will hold a serialized version of Class A. 
    //The scenario requirement is that it can hold any arbitrary BsonDocument of different types 
    public BsonDocument Properties {get;set;} 
} 

var instanceOfClassC = collection.Find(...).First(); 

var data = BsonSerializer.Deserialize<A>(instanceOfClassC.Properties); 

最後一行導致異常波紋管。 如果我將BsonElement忽略到B類的Id屬性,它可以正常工作。 但我需要那個Id屬性!

例外:

類型 'System.FormatException' 的未處理的異常發生在MongoDB.Bson.dll

其他信息:反序列化類NameSpace.A的Children屬性時發生錯誤:元素'Id'不匹配類NameSpace.B的任何字段或屬性。

型「System.FormatException」未處理的異常發生在MongoDB.Bson.dll

這個問題似乎是在MongoDB中,因爲它的「B.Id實際存儲爲「ID」屬性序列化「到存儲之前的BsonDocument。否則相同的模式總是完美的,但是比在寫入時MongoDb會變換Id => _id。

要求:類C.Properties包含任意類型的其他有效類類型,並且在類聲明中不能更改爲類型A.它工作順利 - 除了嵌套的Id屬性!

更新:發現了一個殘酷的黑客解決方案:在發送到MongoDb之前,將BsonDocument中的所有「Id」屬性重命名爲「_id」。然後反序列化按預期工作。 json.Replace(「\」Id \「」,「\」_「\」「)

任何人都有更好的解決方案嗎?

回答

0

一個清潔的解決辦法是:

public class A 
{ 
    public string Id {get;set;} 
    public List<B> Children {get;set;} 
} 
[BsonNoId] // this solves the problem 
public class B 
{ 
    public string Id {get;set;} 
    public string Foo {get;set;} 
    public double Bar {get;set;} 
} 

你也可以做到這一點沒有一個屬性,使用BsonClassMap:

BsonClassMap.RegisterClassMap<B>(cm => 
{ 
    cm.SetIdMember(null); 
}); 

這是usful如果你映射的類型是從不同的圖書館