【问题标题】:Reading null into a nullable int with MongoDB C# driver使用 MongoDB C# 驱动程序将 null 读入可空的 int
【发布时间】:2017-01-11 22:49:08
【问题描述】:

我的 MongoDB 中有数据,其中存储了一个可为空的 int,通常为 null。我在 C# 端的模型的变量为 int? MaterialID

当我运行.Query.FirstOrDefault() 时,我收到错误消息“输入字符串的格式不正确。”每当它尝试从 Mongo 读取空值时(整数工作正常)。

我设法通过改变我的 int 来解决这个问题?到一个字符串,然后再将其转换回一个 int?,但这是一个我真的不喜欢的可怕的 hack。有人对我如何将 Mongo 中的 null 读入我的 int 有任何想法吗?在 C# 方面?

谢谢。

我的 JSON:

 "Collection" : {
        "List" : [ 
            {
                "ID" : "40",
                "StartDate" : ISODate("2013-01-01T00:00:00.000Z"),
                "EndDate" : ISODate("2013-12-31T00:00:00.000Z"),
                "MaterialID" : "3"
            }, 
            {
                "ID" : "40",
                "StartDate" : ISODate("2014-01-01T00:00:00.000Z"),
                "EndDate" : ISODate("2014-09-30T00:00:00.000Z"),
                "MaterialID" : "null"
            }
        ]

【问题讨论】:

  • 你能发布你的对象的 json 吗? (使用非空 MaterialId)
  • @SergeyBerezovskiy,你明白了
  • 所以你的文档没有_id字段?

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


【解决方案1】:

您将 MaterialID 字段作为字符串存储在数据库中(类型 2)。当然,当您尝试将字符串值分配给可空整数时,您会遇到错误。注意:即使null 也存储为带有文本"null" 的字符串。我建议您从修复数据库中的数据开始。您可以从 mongo shell 中执行此操作:

> db.collection.find({MaterialID:{$type:2}}).forEach(
    function(doc){ 
       var materialId = (doc.MaterialID == "null") ? null : new NumberInt(doc.MaterialID);
       db.collection.update({_id:doc._id},{$set:{MaterialID: materialId}});
    })

注意:在您的 json 文档中没有 _id 字段,但我认为它在那里而不是 ID 字段。无论如何,您可以根据需要调整脚本。

更改字段类型后,您到可为空的 int 的映射将正常工作。


顺便说一句,如果由于某种原因您无法修复数据库中的数据,还有另一种选择。您可以使用将转换 int 的自定义 BSON 序列化程序?字符串,反之亦然:

public class NullableIntAsStringSerializer : SerializerBase<int?>
{
    public override void Serialize(
        BsonSerializationContext context, BsonSerializationArgs args, int? value)
    {
        context.Writer.WriteString(value.HasValue ? value.ToString() : "null");
    }

    public override int? Deserialize(
        BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var str = context.Reader.ReadString();
        return str == "null" ? (int?)null : Int32.Parse(str);
    }
}

并将此序列化程序分配给您的属性

[BsonSerializer(typeof(NullableIntAsStringSerializer))]
public int? MaterialID { get; set; }

【讨论】:

  • 谢谢谢尔盖!我仍然是一个新手 Mongo 开发人员,我一直对 NoSQL 的灵活性感到困惑。您的修复工作完美。
  • @MicrosoftExcel 太棒了 :) 顺便说一句,我添加了一个你可以使用的技巧(但在这种情况下修复数据库更好)
猜你喜欢
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多