2017-09-06 59 views
0

具有以下类:BsonExtraElements字典<串,对象>和自定义类作为值失败序列

public class Article 
{ 
    [BsonId] 
    [BsonRepresentation(BsonType.ObjectId)] 
    public string Id { get; set; } 

    public string Name { get; set; } 

    [BsonExtraElements()] 
    public Dictionary<string, Object> OtherData { get; set; } 
} 

我想此对象添加到词典和写入到数据库中:

public class Bird 
{ 
    [BsonElement("_n")] 
    [BsonRequired] 
    public string Name { get; set; } 
    [BsonElement("_s")] 
    [BsonRequired] 
    public string Species { get; set; } 
    [BsonElement("_a")] 
    [BsonRequired] 
    public int Age { get; set; } 
} 

var col = db.GetCollection<Article>("articles"); 

var art = new Article 
{ 
    Name = "Blu" 
}; 

art.OtherData = new System.Collections.Generic.Dictionary<string, object>() 
{ 
    { "bird" , new Bird { Name = "Jerry", Age = 4, Species = "European starling" } } 
}; 

col.InsertOne(art); 

但是这个失败,出现以下异常信息:System.ArgumentException:“.NET类型鸟不能映射到BsonValue”

如果我删除[BsonExtraElements]在致敬,一切顺利,文章在数据库中结束。为什么是这样?属性如何防止序列化?由于该属性不在那里,我的这个自定义类可以由驱动程序序列化。

使用驱动程序版本2.4.4

+0

我报道这个在MongoDB的[JIRA ](https://jira.mongodb.org/browse/CSHARP-2035)。他们已经研究并回答:“这不是真正的预期行为。我们现在假设BsonExtraElements字典中的所有值都是BsonValue的实例,或者可以简单地转换为BsonValue。我们应该能够通过使用序列化器来转换更复杂的值,比如您的Bird类。 我们会考虑在未来的版本中支持这个.' –

回答

1

官方文档(http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/):

你可以设计你的类能够处理可能一BSON文档中反序列化过程中发现有任何多余的元素。为此,您必须拥有BsonDocument类型的属性,并且必须将该属性标识为应该包含找到的任何其他元素的属性(或者您可以将该属性命名为“ExtraElements”,以便默认的ExtraElementsMemberConvention可以找到它自动)。

public MyClass { 
// fields and properties 
[BsonExtraElements] 
public BsonDocument CatchAll { get; set; } 
} 

长话短说,它需要在使用[BsonExtraElements]标签是BsonDocument类型。

干杯!

编辑:我懂了工作,加入

{ "bird" , new Bird { Name = "Jerry", Age = 4, Species = "European starling" }.ToBsonDocument() } 
+0

谢谢你的回答!然而,你链接的文档是旧的。我使用的是C#驱动程序的2.4版本。在那里可以将'[BsonExtraElements]'添加到[dictionary](http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/#supporting-extraelements)。 '这样做,你必须有一个BsonDocument类型的属性(或IDictionary )' –

+0

哦,你没有指定驱动程序版本,所以我很难这样做。您是否尝试将成员重命名为ExtraElements? – BOR4

+0

我给出了一个去,但我仍然得到与重命名的字段相同的错误。我还编辑了这个问题,以包含驱动程序版本。 –

0

使用[BsonDictionaryOptions(DictionaryRepresentation.Document)]代替

public class Article 
{ 
    [BsonId] 
    [BsonRepresentation(BsonType.ObjectId)] 
    public string Id { get; set; } 

    public string Name { get; set; } 

    [BsonDictionaryOptions(DictionaryRepresentation.Document)] 
    public Dictionary<string, Object> OtherData { get; set; } 
} 

这将产生JSON像

{ 
    "_id": ObjectId("5a468f3e28fad22e08c4fa6b"), 
    "Name": "Sanjay", 
    "OtherData": { 
     "stringData": "val1", 
     "boolVal": true, 
     "someObject": { 
      "key1": "val1", 
      "key2": "val2" 
     }, 
     ... 
    } 

} 
相关问题