.NET 4.6 中的 NHibernate 按代码映射抛出 "Cannot extend unmapped class"

NHibernate mapping-by-code in .NET 4.6 throws "Cannot extend unmapped class"

我在 运行ning 项目 运行ning 中使用了几个月的相同 NH 配置,我今天在干净安装 Windows 时打开(安装了 VS 2015 RC,还安装了 .NET 4.6 RC,但项目的目标是 .NET 4.5)

在构建 NH 会话工厂时调用这些行:

var mapper = new AutoMapper();
var mapping = mapper.CompileMappingFor(typeof(Entity).Assembly.GetTypes());
conf.AddMapping(mapping);

最后一行抛出异常:Could not compile the mapping document: mapping_by_code with InnerException Cannot extend unmapped class: [my_namespace].[my_entity_name]。当我遍历 mapping 时,我可以看到名称为 [my_entity_name] 的对象,一切似乎都正常。只有这个对象在扩展这个对象的对象之后的集合中(我不确定它是否有问题或者顺序无关紧要)。

在任何其他计算机上(其他工作站、CI 服务器、生产和开发环境)我们没有注意到这个错误,我想这可能是由安装的 .NET 4.6 引起的,这是唯一的.NET 4.6 的机器。如果我在安装 .NET 4.6 时理解正确,所有以 .NET 4.5 为目标的项目都在 .NET 4.6 运行time 中 运行ning。我也尝试在 VS 2013 中 运行 它,但没有任何变化......我也在检查 .NET 4.6RC 更新日志,但我没有发现任何可能导致此错误的内容。有什么建议吗?


更新: 我在 .NET 4.5 机器上检查了 mapping 集合中项目的顺序,顺序正确(依赖子类在父子类之后) ,因此似乎 GetTypes() 返回的类型顺序(不保证顺序)巧合地在 .NET 4.5 中工作,但在 .NET 4.6 中不起作用,因为 CompileMappingFor 不会重新排序相同类型的映射(这里我有依赖 SubClass -> SubClass)。

是的,原因是 Assembly.GetTypes() 的顺序在 .NET 4.5 和 .NET 4.6 中完全不同。巧合的是 .NET 4.5 生成的订单正在运行......我将其修改为以下代码并且它可以运行。

var types = typeof (Entity).Assembly.GetTypes().Where(t => !t.IsInterface).PartialOrderBy(x => x, new EntityTypeComparer());
var mapping = mapper.CompileMappingFor(types);    

public class EntityTypeComparer : IComparer<Type>
{
    public int Compare(Type x, Type y)
    {           
        if (x == y)
            return 0;
        if (x.IsAssignableFrom(y) || (!x.IsAssignableTo<Entity>() && y.IsAssignableTo<Entity>()))
            return -1;
        if (y.IsAssignableFrom(x) || (!y.IsAssignableTo<Entity>() && x.IsAssignableTo<Entity>()))
            return 1;
        return 0;
    }
}      

编辑: OrderBy 替换为 PartialOrderBy,您可以在此处找到实现 - Topological Sorting using LINQ。这使得拓扑排序而不是常规排序 - 我们有不可比较的对象(比较器中的最后一个 return 0)并且一般的 OrderBy 会产生错误的结果。