史前史:我有一个从XML架构(XSD)生成的类层次结构(一个很大的层次结构)。
MyObj obj;
现在:我需要使用生成的类层次结构解析一个字符串值,它实际上是一个XML对象,然后我需要将该对象放入MongoDB。代码是:
private BsonDocument XmlToBson(string content)
{
MyObj obj;
using (var reader = new StringReader(content))
{
var serializer = new XmlSerializer(typeof(MyObj));
obj = (MyObj) serializer.Deserialize(reader);
}
return obj.ToBsonDocument();
}
问题:层次结构中有很多null子对象,在Robomongo中看起来像这样:
我想避免将空对象添加到数据库中。我知道我可以逐个忽略它们,就像这里描述Ignoring Default Values一样,使用属性或lambda表达式。但由于层次结构庞大而复杂,我不喜欢这种方法。我懒得列出当它们具有空值时必须被忽略的所有属性。更重要的是,该类可以在将来重新生成,支持必须忽略的属性列表将是一场噩梦。
问题:无论对象在层次结构中的哪个位置,如何实现目标并忽略全局空值?我正在使用MongoDB C#驱动程序版本。 2.2。
答案 0 :(得分:8)
通过注册约定包,可以在序列化时将大多数属性的效果应用于所有属性。
在注册IgnoreIfDefaultConvention
下方,在序列化和反序列化时隐式将[IgnoreIfDefault]
属性应用于所有属性。
var anon = new
{
Foo = "bar",
Baz = (string)null,
};
ConventionRegistry.Register("IgnoreIfDefault",
new ConventionPack { new IgnoreIfDefaultConvention(true) },
t => true);
var bsonDocument = anon.ToBsonDocument();
这将生成仅包含Foo
密钥的文档。
如果需要,您还可以在序列化后按名称Remove()
此约定包。
答案 1 :(得分:1)
您还可以应用 MongoDB.Bson.Serialization.Attributes
中的[BsonIgnoreIfNull]
属性
类字段的名称空间,如果您不希望在BSON文档中显示带有空值的字段。
public class Person
{
public string Name { get; set; }
[BsonIgnoreIfNull]
public List<string> Children { get; set; }
}
答案 2 :(得分:0)
实际上,使用 IgnoreIfDefaultConvention
会导致意外行为,因为它会影响所有默认值。例如,上面列表中的值将不会被保存:
如果您只想忽略空值,最好的方法是IgnoreIfNullConvention
。
这是一个例子:
ConventionRegistry.Register("IgnoreIfNullConvention", new ConventionPack { new IgnoreIfNullConvention(true) }, t => true);