我有以下类:MongoDB的反序列化随着鉴别版本
[BsonIgnoreExtraElements]
public class WidgetCollection
{
[BsonId]
public int AccountId { get; set; }
public ReadOnlyCollection<Widget> Widgets { get; set; }
}
[BsonIgnoreExtraElements]
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(OtherObject1), ...)]
public class Widget
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public int Position { get; set; }
public WidgetKind Kind { get; set; }
public bool IsActive { get; set; }
}
在DB一个的此实例的一个例子:
{ "_id" : 2993644, "Widgets" : [ { "_t" : "Widget", "_id" : ObjectId("504797b327e10b1e80c838ac"), "Title" : "My Notes", "Position" : 1, "Kind" : 0, "IsActive" : true } ] }
我然后具有在过滤掉元素的聚合命令“Widgets”数组仅返回其“IsActive”为true的元素。在这种情况下,该命令只是返回整个对象。
var command = new CommandDocument
{
{"aggregate", "myCollection" },
{"pipeline", commandArray }
};
var result = database.RunCommandAs<AggregateResult<WidgetCollection>>(command).Result;
return result;
这是AggregateResult类:
public class AggregateResult<T> : CommandResult
{
public T Result
{
get
{
var result = Response["result"].AsBsonArray.SingleOrDefault().AsBsonDocument;
return BsonSerializer.Deserialize<T>(result);
}
}
}
是的,我知道的SingleOrDefault()AsBsonDocument能区分一个NRE,但现在这不是问题。我已将代码调试到反序列化的位置,并验证了“result”变量包含与上面所示完全相同的BSON。尝试反序列化结果时收到此消息:“在反序列化Community.Widgets.WidgetCollection类的Widgets属性时发生错误:预期的元素名称为'_v',而不是'_id'”。
为什么解串器期望'_v'元素?
UPDATE
我固定上述问题通过改变小部件属性的类型ICollection
。我现在收到此错误:Unknown discriminator value 'Widget'.
对我来说,这是没有意义的,因为文档有"_t" : "Widget"
元素。
我也尝试插入一个派生类,在此之后,“_t”元素的值现在为"[ "Widget", "DerivedClass"]
,并且我得到相同的错误。同样,使用database.FindOneAs<>()
时不会发生这种情况,只有在明确使用BsonSerializer.Deserialize<>()
时才会发生。我尝试添加该代码调用权之前Deserialize()
:
BsonClassMap.RegisterClassMap<Widget>(cm => { cm.AutoMap(); cm.SetIsRootClass(true); });
BsonClassMap.RegisterClassMap<RssFeedWidget>();
但我不能完全确定是哪里初始化代码应该去,我想,如果我是用我的类属性鉴别它是没有必要的。
这里是我的聚集命令
BsonDocument documentMatch = new BsonDocument{{"$match", new BsonDocument{{"_id", documentId}}}};
BsonDocument unwindArray = new BsonDocument{{"$unwind", "$Widgets"}};
BsonDocument arrayMatch = new BsonDocument{{"$match", new BsonDocument{{"Widgets.IsActive", true}}}});
BsonArray commandArray = new BsonArray();
commandArray.Add(documentMatch);
commandArray.Add(unwindArray),
commandArray.Add(arrayMatch);
var command = new CommandDocument
{
{"aggregate", collectionName},
{"pipeline", commandArray}
}
var result = database.RunCommandAs<AggregateResult<WidgetCollection>>(command).Result;
你为什么不走一步,自己调试驱动程序?源代码就在这里:https://github.com/mongodb/mongo-csharp-driver –
良好的通话。它看起来像试图反序列化数组中的元素,它会查找_t字符串,然后查找不存在的_v字符串。我试图寻找_v元素的目的是什么,但我找不到任何东西。 – anthv123
我对BlinkSerializer的参数中使用的有点困惑。反序列化...你使用的是Widget还是WidgetCollection? –