C# .NET4.6中代码的NHibernate映射抛出;无法扩展未映射的类“;
我的项目运行了几个月,其配置与我今天在干净的Windows安装上打开的配置相同(安装了VS 2015 RC,也安装了.NET 4.6 RC,但项目的目标是.NET 4.5) 在NH session factory大楼中,当调用这些线路时:C# .NET4.6中代码的NHibernate映射抛出;无法扩展未映射的类“;,c#,nhibernate,mapping-by-code,.net-4.6,C#,Nhibernate,Mapping By Code,.net 4.6,我的项目运行了几个月,其配置与我今天在干净的Windows安装上打开的配置相同(安装了VS 2015 RC,也安装了.NET 4.6 RC,但项目的目标是.NET 4.5) 在NH session factory大楼中,当调用这些线路时: var mapper = new AutoMapper(); var mapping = mapper.CompileMappingFor(typeof(Entity).Assembly.GetTypes()); conf.AddMapping(mapping
var mapper = new AutoMapper();
var mapping = mapper.CompileMappingFor(typeof(Entity).Assembly.GetTypes());
conf.AddMapping(mapping);
最后一行引发异常:无法编译映射文档:使用InnerException的映射\u by\u code
无法扩展未映射的类:[my\u命名空间].[my\u实体\u名称]
。当我遍历映射时
,我可以看到有一个名为[my_entity_name]
的对象,一切似乎都正常。仅此对象位于扩展此对象的对象之后的集合中(我不确定这是否可能是个问题,或者顺序是否无关紧要)
在任何其他计算机(其他工作站、CI服务器、生产和开发环境)上,我们都没有注意到此错误,我想这可能是由于安装了.NET 4.6造成的,这是唯一一台安装了.NET 4.6的计算机。如果我在安装.NET4.6时理解正确,那么所有针对.NET4.5的项目都在.NET4.6运行时运行。我也试着在VS 2013中运行它,但没有改变。。。我还检查了.NET4.6RC变更日志,但没有发现任何可能导致此错误的内容。有什么建议吗
更新:我在.NET 4.5机器上检查了
映射
集合中项目的顺序,并且顺序正确(依赖子类在父子类之后),因此GetTypes()
返回的类型顺序(不保证顺序)似乎在.NET 4.5中同时工作,但是不能在.NET 4.6中工作,因为CompileMappingFor
不会对相同类型的映射进行重新排序(这里我有dependency SubClass->SubClass)。是的,原因是Assembly.GetTypes()
在.NET 4.5和.NET 4.6中的顺序完全不同。巧合的是,由.NET4.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;
}
}
var types=typeof(Entity).Assembly.GetTypes().Where(t=>!t.IsInterface).PartialOrderBy(x=>x,new EntityTypeComparer());
var-mapping=mapper.CompileMappingFor(类型);
公共类EntityTypeComparer:IComparer
{
公共整数比较(类型x、类型y)
{
如果(x==y)
返回0;
if(x.IsAssignableFrom(y)| |(!x.IsAssignableTo()&&y.IsAssignableTo())
返回-1;
if(y.IsAssignableFrom(x)| |(!y.IsAssignableTo()&&x.IsAssignableTo())
返回1;
返回0;
}
}
编辑:
OrderBy
替换为PartialOrderBy
,您可以在此处找到实现-。这使得拓扑排序取代了常规排序-我们有一些不可比较的对象(比较器中最后返回0),而常规OrderBy可能会产生错误的结果。我在Windows 10(RTM)上遇到了与VS2015(RTM)相同的问题。应用程序仍然以.NET Framework 4.5.2为目标,但正如您所写,“安装.NET 4.6后,所有以.NET 4.5为目标的项目都在.NET 4.6运行时运行”我收到的确切错误是NHibernate.MappingException:无法编译映射文档:mapping_by_code-->NHibernate.MappingException:无法扩展未映射的类
NHibernate版本:4.0.3.4000请小心最后一个返回0
。。。比较算法并不总是比较您直接想到的类型,而是可以通过第三种类型进行比较。假设您有类型A、B、C和C继承自B,在这种情况下,比较器将执行以下操作:A==B。。。A==C。。。然后它假设B==C,结果的顺序是错误的——类型B和C永远不会调用Compare方法!是的,你是对的,这个比较器是错的。实际上,不可能使用OrderBy
和IComparer
,因为继承关系只是一种偏序关系,而不是线性顺序关系。正确的解决方案是使用拓扑排序。我将重写它并更新这个问题…我更新了原始代码,只是OrderBy被PartialOrderBy替换,比较器没有修改。谢谢@gschuager的通知。这里和