但是感觉好复杂,过了一弯又一弯。
使用MongoDB .NET Driver内置
话说这么常用的功能,SDK应该内置了才对,何必舍近求远,。
既然RunCommand可以传递一个类型,那么SDK应该是支持反序列化自定义类型的。
尝试根据返回的结果定义一个新的类:
[BsonIgnoreExtraElements]
private class FindCommandResult
{
[BsonElement("cursor")]
public ResultCursor Cursor { get; set; }
}
[BsonIgnoreExtraElements]
private class ResultCursor
{
[BsonElement("firstBatch")]
public PersonInfo[] Batch { get; set; }
}
private class PersonInfo
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
public DateTime AddTime { get; set; }
}
BsonIgnoreExtraElements、BsonElement、BsonId、BsonRepresentation这些都是SDK内置的Attribute,相关作用大家应该能够一目了然。
再看看查询这块的代码:
var findCommand = BsonDocument.Parse("{"find":"test", limit:1, sort:{AddTime:-1}}");
var findResult = database.RunCommand<FindCommandResult>(findCommand);
代码跑起来:

这个方式相比Json.NET更直接,更简单。
使用查找赋值的方式
为了反序列化,适应MongoDB,定义了一些没有业务意义的类型,加了很多的属性注解,感觉还不够直接显性。
也许只需要数据中的某几个字段,或者根本就没必要定义类型,只需要放到一个列表中。
又查看了BsonDocument的定义,发现可以在运行命令时先反序列化为BsonDocument,然后再根据返回的数据结构使用GetElement获取相关字段的值。
代码如下:
var findCommand = BsonDocument.Parse("{"find":"test", limit:2, sort:{AddTime:-1}}");
var findResult = database.RunCommand<BsonDocument>(findCommand)
.GetElement("cursor").Value.ToBsonDocument()
.GetElement("firstBatch").Value.AsBsonArray.Select(d =>
{
var dbd = d.AsBsonDocument;
return new PersonInfo()
{
Id = dbd.GetElement("_id").Value.AsObjectId.ToString(),
AddTime = dbd.GetElement("AddTime").Value.ToLocalTime(),
Name = dbd.GetElement("Name").Value.ToString(),
};
}).ToList();
运行后直接返回List<PersonInfo> ,更贴近业务需求。
这是本文中最简单的方式了。
如果做的更通用点,可以在这里通过反射自动实例化相关类型,不过这不如直接使用SDK内置的反序列化方式了。










