使用PullFilter删除数组元素时出现异常

时间:2016-11-23 20:21:35

标签: c# mongodb serialization casting

  

无法投射类型的对象   输入'MongoDB.Bson.Serialization.Serializers.BsonValueSerializer'   'MongoDB.Bson.Serialization.IBsonSerializer'

尝试使用C#驱动程序(2.2.4或2.3.0)从MongoDB中的子文档列表执行拉取。

这是我更新的方式:

FilterDefinitionBuilder<Event> filter = new FilterDefinitionBuilder<Event>();
UpdateDefinitionBuilder<Event> update = new UpdateDefinitionBuilder<Event>();
_eventRepo.FindAndUpdate(filter.Eq("EventId", eventid), 
update.PullFilter("Documents", filter.Eq("DocId", docid)));

被调用的存储库方法:

public void FindAndUpdate(FilterDefinition<T> filter, UpdateDefinition<T> update)
{
    _context.Collection<T>().FindOneAndUpdate(filter, update);
}

这是MongoDB文档的样子:

{
  "_id" : ObjectId("5825f74919c55e0c9c4727ee"), 
  "EventId" : "1234-5789",
  "Documents" : [
     {
        "DocId" : "07c03673-c572-4f56-aaad-0edb52b3a06c", 
        "Name" : "test.pdf"
     }
  ]
}

这是我得到的例外:

An exception of type 'System.InvalidCastException' occurred in MongoDB.Driver.dll but was not handled in user code
Additional information: Unable to cast object of type 'MongoDB.Bson.Serialization.Serializers.BsonValueSerializer' to type 'MongoDB.Bson.Serialization.IBsonSerializer`1[MongoDB.Bson.BsonDocument]'.

Stack trace:
at MongoDB.Driver.PullUpdateDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOneAndUpdateOperation[TProjection](FilterDefinition`1 filter, UpdateDefinition`1 update, FindOneAndUpdateOptions`2 options)
at MongoDB.Driver.MongoCollectionImpl`1.FindOneAndUpdate[TProjection](FilterDefinition`1 filter, UpdateDefinition`1 update, FindOneAndUpdateOptions`2 options, CancellationToken cancellationToken)

该异常没有任何意义,因为BsonValueSerializer实现/继承IBsonSerializerDocumentation),所以我希望Render应该能够{ {1}}。

显然这是在C#BSon驱动程序的BsonValueSerializer方法内。这是司机的错误还是我做错了什么?

我发现人们以同样的方式进行拉动(here)并且它似乎适用于他们。 我发现了一个非常类似的问题(here),但解决方案和讨论无法帮助我解决问题。

1 个答案:

答案 0 :(得分:0)

过滤器已键入,您必须将过滤器与过滤的内容进行匹配。

您对集合的过滤器应为FilterDefinition&lt; Event&gt;。

与PullFilter一起使用的过滤器应该是FilterDefinition&lt; Document&gt ;.

这不会在编译时捕获,因为您使用“DocId”来标识字段,因此没有与该字段关联的类型信息。从传递给PullFilter的过滤器推断出该字段的类型,PullFilter是Event的过滤器。

我建议使用过滤器和更新构建器的类型版本。这是使用类型化版本重写的代码,这会导致编译时错误:

var filter = Builders<Event>.Filter.Eq(x => x.EventId, "abc");
var update = Builders<Event>.Update.PullFilter(x => x.Documents, Builders<Event>.Filter.Eq(x => x.DocId, "abc"));
collection.FindOneAndUpdate(filter, update);

这是使用Document而不是在上一次使用Builders中使用Event的代码:

var filter = Builders<Event>.Filter.Eq(x => x.EventId, "abc");
var update = Builders<Event>.Update.PullFilter(x => x.Documents, Builders<Document>.Filter.Eq(x => x.DocId, "abc"));
collection.FindOneAndUpdate(filter, update);