我有一个A类,一个B和C
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属性!
例外:
未处理的类型&#39; System.FormatException&#39;发生在MongoDB.Bson.dll
其他信息:反序列化NameSpace.A类的Children属性时发生错误:元素&#39; Id&#39;与NameSpace.B类的任何字段或属性都不匹配。
未处理的类型&#39; System.FormatException&#39;发生在MongoDB.Bson.dll
问题似乎是属性B.Id实际上存储为&#34; Id&#34;在MongoDb,因为它&#34;序列化&#34;存储前到BsonDocument。否则相同的模式总是完美的,但是MongoDb将转换为Id =&gt;在写作时_id。
要求:类C.Properties包含任意种类的其他有效类类型,并且不能在类声明中更改为类型A.它工作顺利 - 除了嵌套的Id属性!
更新:找到了一个残酷的黑客解决方案:重命名所有&#34; Id&#34; BsonDocument中的属性为&#34; _id&#34;在运送到MongoDb之前。然后反序列化按预期工作。我用字符串替换json来做到这一点 json.Replace(&#34; \&#34; Id \&#34;&#34;,&#34; \&#34; _id \&#34;&#34;)
任何人都有更好的解决方案吗?
答案 0 :(得分:1)
更清洁的解决方案是:
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);
});
如果要映射的类型来自不同的库
,那么这是有用的