"无法确定"的序列化信息。 MongoDB复杂类型的错误等于null过滤器

时间:2015-05-07 19:34:49

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

我在尝试对MongoDB.Driver 2.0中的复杂类型对象运行等效过滤器时遇到以下错误:

  

InvalidOperationException:无法确定序列化信息   e => e.Deletion。      在MongoDB.Driver.ExpressionFieldDefinition 2.Render(IBsonSerializer 1观察   ntSerializer,IBsonSerializerRegistry serializerRegistry)      在MongoDB.Driver.SimpleFilterDefinition 2.Render(IBsonSerializer 1个文件   erializer,IBsonSerializerRegistry serializerRegistry)      在MongoDB.Driver.AndFilterDefinition 1.Render(IBsonSerializer 1 documentSeri   alizer,IBsonSerializerRegistry serializerRegistry)      在MongoDB.Driver.MongoCollectionImpl 1.FindOneAndUpdateAsync[TProjection](Fi lterDefinition 1个过滤器,UpdateDefinition 1 update, FindOneAndUpdateOptions 2 op   tions,CancellationToken cancellationToken)

这是过滤器:

Builders<TEntity>.Filter.Eq(e => e.Deletion, null)

为了重现,请使用MongoDB.Driver 2.0.0版本运行以下代码:

public sealed class OccuranceWithReason
{
    public OccuranceWithReason() : this(null)
    {
    }

    public OccuranceWithReason(string reason)
    {
        Reason = reason;
        OccuredOn = DateTime.UtcNow;
    }

    public string Reason { get; private set; }
    public DateTime OccuredOn { get; private set; }
}

public interface IDeletable
{
    OccuranceWithReason Deletion { get; }
}

public abstract class BaseEntity : IDeletable
{
    protected BaseEntity()
    {
        Id = ObjectId.GenerateNewId().ToString();
    }

    public string Id { get; private set; }
    public int PeekedCount { get; set; }
    public OccuranceWithReason Deletion { get; private set; }
}

public class FooEntity : BaseEntity
{
}

class Program
{
    static void Main(string[] args)
    {
        MongoConfig.Configure();
        var client = new MongoClient();
        var db = client.GetDatabase("foo");
        var fooCol = db.GetCollection<FooEntity>("foos");
        var foo = PeekForInsertSync(fooCol);
    }

    public static TEntity PeekForInsertSync<TEntity>(IMongoCollection<TEntity> collection)
        where TEntity : BaseEntity
    {
        var query = Builders<TEntity>.Filter.And(
            Builders<TEntity>.Filter.Eq(e => e.Deletion, null),
            Builders<TEntity>.Filter.Lte(e => e.PeekedCount, 10)
        );

        return collection.Find(query).FirstOrDefaultAsync().Result;
    }

}

internal static class MongoConfig
{
    public static void Configure()
    {
        RegisterConventions();
        RegisterGlobalSerializationRules();
        ConfigureEntities();
        ConfigureValueObjects();
    }

    private static void RegisterConventions()
    {
        var pack = new ConventionPack { new CamelCaseElementNameConvention(), new IgnoreIfNullConvention(false) };
        ConventionRegistry.Register("all", pack, t => true);
    }

    private static void RegisterGlobalSerializationRules()
    {
        BsonSerializer.UseNullIdChecker = true;
    }

    private static void ConfigureEntities()
    {
        BsonClassMap.RegisterClassMap<BaseEntity>(cm =>
        {
            cm.MapMember(c => c.Id).SetSerializer(new StringSerializer(BsonType.ObjectId));
            cm.SetIdMember(cm.GetMemberMap(c => c.Id));
        });
    }

    private static void ConfigureValueObjects()
    {
        BsonClassMap.RegisterClassMap<OccuranceWithReason>(cm =>
        {
            cm.AutoMap();
            cm.MapCreator(occurance => new OccuranceWithReason(occurance.Reason));
        });
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

问题在于BaseEntity对象序列化注册。未映射Deletion属性。自动映射所有字段解决了问题:

BsonClassMap.RegisterClassMap<BaseEntity>(cm =>
{
    cm.AutoMap();
    cm.MapMember(c => c.Id).SetSerializer(new StringSerializer(BsonType.ObjectId));
    cm.SetIdMember(cm.GetMemberMap(c => c.Id));
});