2016-11-23 84 views
2

Unable to cast object of type 'MongoDB.Bson.Serialization.Serializers.BsonValueSerializer' to type 'MongoDB.Bson.Serialization.IBsonSerializer'使用PullFilter刪除數組元素時出現異常

嘗試使用C#驅動程序(2.2.4或2.3.0)從MongoDB中的子文檔列表執行Pull操作。

這是我做了更新:​​

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應該能夠採取BsonValueSerializer

顯然這是在C#BSon驅動程序的FindOneAndReplace方法中。這是司機的錯誤還是我做錯了什麼?

我發現那些人以同樣的方式拉(here),它似乎爲他們工作。 我發現看起來像一個非常類似的問題(here),但解決方案和討論無法幫助我修復我的問題。

回答

0

過濾器是鍵入的,您必須將過濾器與它們過濾的內容進行匹配。

您對該集合的過濾器應該是FilterDefinition < Event>。

您使用PullFilter的過濾器應該是FilterDefinition < Document>。

這不會在編譯時被捕獲,因爲您使用「DocId」來標識該字段,因此沒有與該字段關聯的類型信息。該字段的類型是從傳遞給PullFilter的過濾器推斷的,該過濾器是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); 

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); 

使用,而不是事件文檔在建築工地的最近使用下面的代碼