2017-09-07 49 views
0

有誰知道更新和插入的序列化有什麼區別,以及如何使其相等?我遇到的問題是休耕:
比方說,我們有下面的類(忽略它沒有MongoId,因爲它是不相關)MongoDB插入vs複雜類型的更新序列化差異

class Custom 
{ 
    public string ID { get; set; } 
    public Dictionary<string, string> Dict { get; set; } 
} 

當我使用生成的JSON看起來像這樣Insert命令

{ 
    "ID" : "id", 
    "Dict" : 
    { 
     "Key": "Val" 
    } 
} 

這是符合市場預期,但使用更新命令後的Json改變這種

{ 
    "ID" : "id", 
    "Dict" : 
    { 
     "_t" : "System.Collections.Generic.Dictionary`2[System.String,System.String]", 
     "_v" : 
     { 
      "Key": "Val" 
     } 
    } 
} 

的問題,這是BSON串行器遇到_t/_v語法時會引發錯誤。那麼,我如何才能使Update序列化與Insert相同呢?

注:
驅動程序版本是2.4.4
TDocument IMongoCollection的總是BsonDocument
字典僅僅是一個例子,這種情況與具有包括數組

編輯
復值的任何數據類型 這是一個簡單的代碼版本。

static void Main(string[] args) 
{ 
    MongoDB.Driver.MongoClient client = new MongoDB.Driver.MongoClient("mongodb://localhost"); 
    MongoDB.Driver.IMongoDatabase db = client.GetDatabase("TestBase"); 
    MongoDB.Driver.IMongoCollection<MongoDB.Bson.BsonDocument> coll = db.GetCollection<MongoDB.Bson.BsonDocument>("TestColl"); 
    Dictionary<string, string> tmpDict = new Dictionary<string, string>(); 
    object tmpDict_o = null; 

    tmpDict.Add("Key", "Val"); 
    tmpDict_o = tmpDict; 

    coll.DeleteMany(MongoDB.Driver.Builders<MongoDB.Bson.BsonDocument>.Filter.Empty); 

    coll.InsertOne(MongoDB.Bson.BsonDocumentWrapper.Create(new Custom() { ID = "id", Dict = tmpDict })); 

    Console.ReadLine(); 

    coll.UpdateMany(MongoDB.Driver.Builders<MongoDB.Bson.BsonDocument>.Filter.Empty, MongoDB.Driver.Builders<MongoDB.Bson.BsonDocument>.Update.Set("Dict", tmpDict_o)); 
    } 

如果您在UpdateMany改變tmpDict_o到tmpDict它將按預期工作,但我不知道變量是什麼類型的值,它必須被存儲在對象。 (原始函數將任意類型和提取與反射屬性值)

編輯2
通過MongoDB.Driver調試我發現,蒙戈威懾的哪種類型的場是通過查看IMongoCollection的TDocument,並且通過使用BsonDocument它將始終採用默認序列化程序(對於System.Object)。所以我的下一個解決方案是打開兩個集合;一個用於插入的BsonDocument,另一個用於更新的類型(在本例中爲Custom)。在這種情況下,字典的更新狀況良好,但數組更糟。字符串數組被串行化爲值爲「String [] Array」的字符串,而複雜類型的數組仍然具有_t/_v語法。

+0

我們可以看到完整的代碼嗎? – BOR4

+0

我現在還沒有確切的代碼,所以我會編輯我的問題。簡而言之。插入是通過使用BsonDocumentWrapper.Create創建文檔並調用InsertOne來完成的。通過使用Set(「field」,value)構建過濾器來完成更新,其中值可以是任何類型(變量類型是對象)並調用UpdateMany。 –

回答

0

回答我自己的問題。我寫的編輯2部分爲真,如果TDocument是BsonDocument,則文檔序列化器將設置爲BsonDocumentSerializer,但字段序列化器將在UpdateDefinitionBuilder的Set方法中解析。因爲變量聲明爲

object tmpDict_o = null; 

TField將始終是對象。要修復此行爲,您可以聲明變量爲

dynamic tmpDict_o = null; 

因此TField將設置爲正確的類型。

注意:
雖然此解決方案的作品,您必須始終宣佈您的類爲public,否則由於某種原因它會回退到_t/_v語法。