InvalidOperationException:无法使用在抽象 class 上声明的构造函数编译 NewExpression

InvalidOperationException: Can't compile a NewExpression with a constructor declared on an abstract class

尝试从 mongodb 检索对象时出错:

InvalidOperationException: Can't compile a NewExpression with a constructor declared on an abstract class

我的class是:

public class App 
{
    public List<Feature> Features { get; set; }
}

public abstract class Feature
{
    public string Name { get; set; }
}

public class ConcreteFeature : Feature
{
    public string ConcreteProp { get; set; }
}

不确定为什么会出现抽象问题。我看,mongodb 记录了 _t: "ConcreteFeature" 类型名称,它具有反序列化它的一切。我没有抽象的构造函数 class.

想法?

我需要为 BsonClassMap 列出 "KnownTypes" 以使其工作:

BsonClassMap.RegisterClassMap<Feature>(cm => {
    cm.AutoMap();
    cm.SetIsRootClass(true);

    var featureType = typeof(Feature);
    featureType.Assembly.GetTypes()
        .Where(type => featureType.IsAssignableFrom(type)).ToList()
        .ForEach(type => cm.AddKnownType(type));
});

这样,即使您添加了新类型,只要它们在 1 个程序集中,您就不需要修改代码。更多信息 here.

1.On摘要class使用

[BsonDiscriminator(Required = true)]
[BsonKnownTypes(typeof(ConcreteFeature)]
public abstract class Feature
{
    public string Name { get; set; }
}


public class ConcreteFeature : Feature
{
    public string ConcreteProp { get; set; }
}

您永远不会将摘要 class 直接存储在数据库中。整个已知类型的东西只是如果你需要类型鉴别器中的继承树,这通常是矫枉过正的。序列化程序确实需要提前了解您的具体 classes,因此以下内容就足够了。

BsonClassMap.RegisterClassMap<ConcreteFeature>();

假设您要定期添加子 classes,那么您可以使用反射并以这种方式注册它们。