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

标签 c# mongodb serialization casting

Unable to cast object of type 'MongoDB.Bson.Serialization.Serializers.BsonValueSerializer' to type '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 实现/继承 IBsonSerializer ( Documentation ),所以我希望 Render应该能够采用 BsonValueSerializer

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

我发现有人以同样的方式执行拉动 ( here ),这似乎对他们有用。 我发现了一个看起来非常相似的问题 ( here ),但解决方案和讨论无法帮助我解决我的问题。

最佳答案

过滤器是键入的,您必须将过滤器与其过滤的内容相匹配。

您对集合的过滤器应该是 FilterDefinition

与 PullFilter 一起使用的过滤器应该是 FilterDefinition

这不会在编译时被捕获,因为您使用“DocId”来标识该字段,因此没有与该字段关联的类型信息。字段的类型是从传递给 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);

这是上次使用 Builders 时使用 Document 而不是 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);

关于c# - 使用 PullFilter 删除数组元素时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40773525/

相关文章:

c# - UITableView 中的随机 "Could not load NIB in bundle"

javascript:如何在没有jquery或其他库的情况下将表单数据序列化为字符串

mongodb - 检查数组包含元素 mongodb

mongodb - meteor 没有开始

node.js - Mocha 在与 Mongoose 连接时执行后挂起

json - Spark + Json4s 序列化问题

serialization - 如何在 IPython 中安装 dill?

java - 运算符 >> 不能应用于 char 和 long 类型的操作数

C# 8 可空值和结果容器

c# - 如何从 Linq 中的逗号分隔字符串中选择标记和索引