ToString在BsonDocument

时间:2016-08-18 23:03:47

标签: c# mongodb-.net-driver

我将现有项目从1.10.0 Mongo Driver升级到2.2.4,并在继承自MongoDB.Bson.BsonDocument的类中遇到了一些意外行为。原始开发人员使用名为BsonDocument的类扩展了BsonDocumentWithNulls,其目的是将null转换为BsonNull.Value

在单元测试中Assert.AreEqual(new BsonDocument("foo", "bar"), new BsonDocumentWithNulls("foo", "baz"));失败,但错误消息并未识别BsonDocumentWithNulls对象中的值。特别是错误消息是Assert.AreEqual failed. Expected:<{ "foo" : "bar" }>. Actual:<[{ }]>.我知道这与ToString有关,但我不知道如何解决它。

这是BsonDocumentWithNulls的实现,它与1.10.0的Mongo驱动程序一起使用,但不适用于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;
}

1 个答案:

答案 0 :(得分:0)

这更像是一个黑客而不是答案,但它让我解决了我遇到的问题,因为BsonDocumentWithNulls只是实现了构造函数,所以这是一个相当容易的解决方法。

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