如何将对默认构造函数的“空”引用从 MongoDB 映射到 POCO
本文关键字:引用 MongoDB 映射 POCO 默认 构造函数 | 更新日期: 2023-09-27 18:31:25
我正在将MongoDB文档映射到C#对象(有关一些背景,请参阅此问题),并且一切正常,但是我开始发现一些为空的条目。原因是XML以前只有<VehicleEntry></VehicleEntry>
标记,因此它作为"null"插入到BsonDocument的数组中。
我可以理解这是预期的行为,但是当我将其映射到我编写的VehicleEntry
类时,它显示为空对象。在我的映射类中,我列出了一堆 BsonDefaultValues,甚至添加了一个默认构造函数,但看起来如果数据库中的值为 'null',它将创建一个 'null' 引用对象。
如何进行设置以将空引用与所有默认值匹配到对象?
如果您创建自己的 BsonSerializers 并将其分配给 VehicleEntry 类型,那么您将能够说该值是否为 null,然后返回一个default(VehicleEntry)
[TestFixture]
public class StackQuestionTest
{
[Test]
public void GivenABsonDocumentWithANullForAnPossibleEmbeddedDocument_When_ThenAnInstanceIsSetAsTheEmbeddedDocument()
{
BsonSerializer.RegisterSerializationProvider(new VehicleEntryBsonSerializationProvider());
var document = new BsonDocument()
{
{"OtherProperty1", BsonString.Create("12345")},
{"OtherProperty2", BsonString.Create("67890")},
{"VehicleEntry", BsonNull.Value},
};
var rootObject = BsonSerializer.Deserialize<RootObject>(document);
Assert.That(rootObject.OtherProperty1, Is.EqualTo("12345"));
Assert.That(rootObject.OtherProperty2, Is.EqualTo("67890"));
Assert.That(rootObject.VehicleEntry, Is.Not.Null);
Assert.That(rootObject.VehicleEntry.What, Is.EqualTo("Magic"));
}
}
public class VehicleEntrySerializer : BsonClassMapSerializer<VehicleEntry>
{
public override VehicleEntry Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
if (context.Reader.GetCurrentBsonType() == BsonType.Null)
{
context.Reader.ReadNull();
return new VehicleEntry();
}
return base.Deserialize(context, args);
}
public VehicleEntrySerializer(BsonClassMap classMap) : base(classMap)
{
}
}
public class VehicleEntryBsonSerializationProvider : IBsonSerializationProvider
{
public IBsonSerializer GetSerializer(Type type)
{
if (type == typeof(VehicleEntry))
{
BsonClassMap bsonClassMap = BsonClassMap.LookupClassMap(type);
return new VehicleEntrySerializer(bsonClassMap);
}
return null;
}
}
public class RootObject
{
public string OtherProperty1 { get; set; }
public string OtherProperty2 { get; set; }
public VehicleEntry VehicleEntry { get; set; }
}
public class VehicleEntry
{
public string What { get; set; } = "Magic";
}
请参阅 http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/serialization/
一种解决方案是将 LINQ 更改为仅返回列表中不为 null 的值:
var results = collection.AsQueryable()
.Where(v => v.ProjectName.Equals("input")
.SelectMan(v => v.VehicleEntries)
.Where(i => i != null)
.ToList();
这并不能解决 null 值存在的问题,但它会在任何结果中呈现它,并在显示数据时避免 NPE。