我有以下POCO课程:
class MyClass {
public Objectid _id {get;set;}
public string property1 {get;set;}
public string property2 {get;set;}
public int property3 {get;set;}
}
该对象存储在MongoDb集合中。数据在生成的bson中具有正确的数据类型:
property1: "SomeString"
property2: "12345"
property3: 98765
当我尝试查询集合时:
var items = db.GetCollection<MyClass>("MyClass").AsQueryable().Select(x => x.property1 == "SomeString").ToList();
我收到一条错误,指出无法反序列化property2: 无法从BsonType'Int64'
反序列化'String'我试图将数据库中的bson文档中的字符串值反序列化为对象上的字符串值。
为什么BsonSerializer会尝试将其转换为十进制?在这种情况下,该值恰好是数字,但该字段在类中定义为字符串,因为该值通常是字母数字。
我正在使用VS2013中的MongoDb.Driver v2.4软件包。
答案 0 :(得分:0)
对于Mongo属性类型更改,您需要为该属性编写自己的Serializer。
这是原始对象,您已将其中几个对象保存到Mongo。
public class TestingObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int TestingObjectType { get; set; }
}
现在我们需要将TestObjectType从int更改为字符串
这是我们的新班级
public class TestingObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string TestingObjectType { get; set; }
}
然后你会得到
无法从BsonType'Int64'
反序列化'String'
您需要的是一个序列化程序来为您处理转换。
public class TestingObjectTypeSerializer : IBsonSerializer
{
public Type ValueType { get; } = typeof(string);
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
if (context.Reader.CurrentBsonType == BsonType.Int32) return GetNumberValue(context);
return context.Reader.ReadString();
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
context.Writer.WriteString(value as string);
}
private static object GetNumberValue(BsonDeserializationContext context)
{
var value = context.Reader.ReadInt32();
switch (value)
{
case 1:
return "one";
case 2:
return "two";
case 3:
return "three";
default:
return "BadType";
}
}
}
关键部分是Deserialize方法。仅当类型为int32时,才要运行转换逻辑。如果类型是其他任何东西,我们将假设它已经是一个字符串并返回该值。
Serialize Just WriteString out和更新或保存的任何文档都将新值作为字符串。
现在您只需要更新您的对象,告诉该属性使用您的Serializer
public class TestingObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
[BsonSerializer(typeof(TestingObjectTypeSerializer))]
public string TestingObjectType { get; set; }
}
下次从Mongo阅读时,您不应该收到错误。