在MongoDb集合查询中无法从ObjectId反序列化为String

时间:2019-03-29 10:03:28

标签: c# mongodb casting mongodb-.net-driver

无论何时我尝试从集合中获取ID列表:

var messages = db.GetCollection<MessageExchange>(collectionName);
var ids = messages
   .AsQueryable()
   .Where(_=> true)
   .Select(x => x.Id)
   .ToList();

我遇到强制转换错误:

  

System.FormatException HResult = 0x80131537消息=无法   从BsonType'ObjectId'反序列化'String'。来源= StackTrace:

我无法修改类的定义,因为它无法在包中实现。因此,解决方案:

[BsonRepresentation(BsonType.ObjectId)] 

在其上 不可能 。基于this

是否可以在Linq查询中强制转换?

3 个答案:

答案 0 :(得分:3)

否,因为db.GetCollection<MessageExchange>将集合定义为强类型对象,驱动程序将结合执行的任何其他逻辑(使用linq或其他方式)对集合进行处理。

您最好的选择是:

  1. 在您自己的代码中定义一个与Mongo Collection兼容的类,然后使用该类对结果db.GetCollection<MyCustomMessageExchange>进行反序列化,然后将其与上面的linq查询一起使用以仅选择ID。

  2. 只需使用默认的BsonDocument来定义您的收藏并使用投影: db.GetCollection<BsonDocument>.Find(new BsonDocument()).Project("{_id: 1}").ToList()

答案 1 :(得分:2)

您绝不打算使用包中的内容-如果您知道类的定义,我建议您在项目内滚动自己的MessageExchange并使用其通过驱动程序查询集合

这还允许您仅获取所需的字段(在新类上使用[BsonIgnoreExtraElements]属性),而不获取程序包的作者强加给您的字段。

如果对于您的程序流程和结构,绝对需要使用类型MessageExchange,则建议使用类似AutoMapper的内容从您自己的类型转换回原始类型。

答案 2 :(得分:1)

ObjectId structure实现了ToString方法,使您可以将对象转换为其字符串表示形式。

所以我认为你可以做到:

var messages = db.GetCollection<MessageExchange>(collectionName);
var ids = messages
   .AsQueryable()
   .Where(_=> true)
   .Select(x => x.Id.ToString())
   .ToList();