MongoDB - 如何忽略反序列化错误

问题描述 投票:0回答:3

我正在使用 MongoDB CSharp 驱动程序来检索数据集合。不幸的是,其中一些数据不是很“干净”,因为某些字段同时是字符串和整数。正如预期的那样,反序列化过程每次遇到与正确类型不匹配的数据时都会引发异常。

我在网络上和 StackOverflow 上进行了广泛的搜索,但没有运气。有没有办法在反序列化时简单地处理/忽略异常并移至下一条记录?

我的代码看起来与此类似:

        MongoClient client = new MongoClient(MongoConnectionString);
        MongoServer server = client.GetServer();
        MongoDatabase database = server.GetDatabase(DatabaseName);

        MongoCollection<BookingLines> bookingLines = database.GetCollection<BookingLines>("bookinglines");

        var query = from e in bookingLines.AsQueryable() where e.Status != "void" select e;

代码通常会在上面的最后一行抛出错误。我还尝试将 [BsonIgnore] 属性添加到某些字段。

任何想法或建议都会非常有帮助。

c# mongodb deserialization mongodb-.net-driver
3个回答
5
投票

如果结构和字段数据类型存在很大差异,则无需付出大量额外努力就无法使用强类型对象。我建议您考虑使用

BsonDocument
,它将允许对任何文档进行序列化和反序列化,如各种教程此处所示。

如果需要,您也可以将其用作中间格式,并运行一些清理代码以将其转换为强类型 C# 类。

如果您想使用强类型类,您还可以为各种字段创建自定义序列化程序(如此处所示),或控制完整的序列化过程,如此处所述。


1
投票

您能够在插入之前清理数据吗?一般来说,就像 SQL 一样,您不想将垃圾放入数据库中。

另一种方法(如果您不需要这些不可靠的字段)就是不将它们包含在 BookingLines 对象中?


0
投票

您可以尝试使用

BsonClassMapSerializer<T>
作为自定义解串器:

public class CustomIgnoreErrorsSerializer<T> : BsonClassMapSerializer<T>
{
    public CustomIgnoreErrorsSerializer(BsonClassMap classMap) : base(classMap) { }

    public override T Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        try
        {
            return base.Deserialize(context, args);
        }
        catch (Exception ex)
        {
            while (context.Reader.State != BsonReaderState.EndOfDocument)
            {
                if (context.Reader.State == BsonReaderState.Name)
                    context.Reader.SkipName();
                if (context.Reader.State == BsonReaderState.Value)
                    context.Reader.SkipValue();
                if (context.Reader.State == BsonReaderState.Type)
                    context.Reader.ReadBsonType();
            }
            context.Reader.ReadEndDocument();
            return default(T);
        }
    }
}

您需要做一些额外的工作,包括将

BsonReader
跳过到当前文档的末尾。

然后要注册这个反序列化器,因为它是一个

BsonClassMapSerializer
类型,您需要传递该类型的类映射,并且您必须为您希望应用到的每个集合类型执行此操作。

var cm = BsonClassMap.LookupClassMap(typeof(MyType));
BsonSerializer.RegisterSerializer(new CustomIgnoreErrorsSerializer<MyType>(cm));
© www.soinside.com 2019 - 2024. All rights reserved.