2016-08-18 21 views
1

我正在將現有項目從1.10.0 Mongo Driver升級到2.2.4,並在繼承自MongoDB.Bson.BsonDocument的類中遇到一些意外行爲。原始開發者將BsonDocument擴展爲BsonDocumentWithNulls,其目的是將null轉換爲BsonNull.ValueToString在BsonDocument的子類中的行爲不像預期的那樣

在單元測試Assert.AreEqual(new BsonDocument("foo", "bar"), new BsonDocumentWithNulls("foo", "baz"));失敗,因爲它應該但錯誤消息不能識別BsonDocumentWithNulls對象中的值。特別是錯誤消息是Assert.AreEqual failed. Expected:<{ "foo" : "bar" }>. Actual:<[{ }]>.我知道這與ToString有關,但我不知道如何解決它。

這是BsonDocumentWithNulls的實現,它與Mongo驅動程序的1.10.0一起使用,但不是版本2.2.4。

public sealed class BsonDocumentWithNulls : BsonDocument 
    { 
     public BsonDocumentWithNulls() 
     { } 

     public BsonDocumentWithNulls(string key, BsonValue value) 
     { 
      if (value == null) 
       Add(key, BsonNull.Value); 
      else 
       Add(key, value); 
     } 

     public BsonDocumentWithNulls(IDictionary<string, object> dictionary) 
     { 
      foreach (var keyValue in dictionary) 
      { 
       if (keyValue.Value == null) 
        Add(keyValue.Key, BsonNull.Value); 
       else 
        Add(keyValue.Key, BsonValue.Create(keyValue.Value)); 
      } 
     } 
    } 

爲了增加混亂,我可以做出以下斷言在單元測試,一切正常,這告訴我的價值實際上是被存儲在內存中。

BsonDocument expected = new BsonDocument("foo", "bar"); 
BsonDocumentWithNulls actual = new BsonDocumentWithNulls("foo", "bar"); 

Assert.AreEqual(expected["foo"], actual["foo"]); 
Assert.AreEqual(expected.GetElement("foo"), actual.GetElement("foo")); 
Assert.AreEqual(expected, actual); 
//And just for sanity 
Assert.AreEqual("bar", actual["foo"]); 

要嘗試解決問題,我試着用各種實現覆蓋ToString。

public override string ToString() 
{ 
    return base.ToString(); 
} 

public override string ToString() 
{ 
    BsonDocument doc = this.AsBsonDocument; 
    return doc.ToString(); 
} 

我的一個更天真的/創造性的嘗試,但我會讓你成爲法官,如果它的創意或天真。

public override string ToString() 
{ 
    string retVal = string.Empty; 

    foreach(var val in this.Elements) 
    { 
     retVal += string.Format("{2}, \"{0}\" : \"{1}\" {3}", val.Name, val.Value, "{", "}"); 
    } 
    return retVal; 
} 

回答

0

這更是一個黑客不是一個答案,但它讓我通過我是有這個問題,因爲BsonDocumentWithNulls只實現constuctors它是圍繞一個相當輕鬆的工作。

public sealed class BsonDocumentWithNulls : BsonDocument 
    { 
     public BsonDocument doc { get; set; } 

     public BsonDocumentWithNulls() 
     { 
      doc = new BsonDocument(); 
     } 

     public BsonDocumentWithNulls(string key, BsonValue value) 
     { 
      doc = new BsonDocument(); 
      if (value == null) 
       doc.Add(key, BsonNull.Value); 
      else 
       doc.Add(key, value); 
     } 

     public BsonDocumentWithNulls(IDictionary<string, object> dictionary) 
     { 
      doc = new BsonDocument(); 
      foreach (var keyValue in dictionary) 
      { 
       if (keyValue.Value == null) 
        doc.Add(keyValue.Key, BsonNull.Value); 
       else 
        doc.Add(keyValue.Key, BsonValue.Create(keyValue.Value)); 
      } 
     } 

     public override string ToString() 
     { 
      return doc.ToString(); 
     } 

     public BsonDocument ToBsonDocument() 
     { 
      return doc; 
     } 
    } 

這個類的最常見的用法是像

var doc = new BsonDocumentWithNulls { 
    {"key1" : 1 }, 
    {"key2" : "val2" } 
}; 

它真的很容易只是釘在。 ToBsonDocument()

var doc = new BsonDocumentWithNulls { 
    {"key1" : 1 }, 
    {"key2" : "val2" } 
}.ToBsonDocument();