.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 会产生错误的结果。
我在 运行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 会产生错误的结果。