使用带有NHibernate命名查询的未映射类

我正在使用NHibernate的自定义命名查询,我想返回Person对象的集合。 Person对象没有映射到NHibernate映射,这意味着我得到以下exception:

System.Collections.Generic.KeyNotFoundException:给定的键不在字典中。

在创建Session时会抛出它,因为它在调用NHibernate.Cfg.Mappings.GetClass(String className)时找不到类名。 这一切都是可以理解的,但我想知道是否有任何方法告诉NHibernate使用该类,即使我没有它的映射?

你为什么不用:

query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));

它将使用列别名作为属性名称将查询中每列的数据插入Person对象属性。

如何创建一个返回未映射类型实例的查询?

我认为Michal在这里有一个观点,也许你应该看看预测。 (至少,这是我认为你正在寻找的)。

您在某些映射类型上创建查询,然后,您可以将该查询“投影”到“DTO”。 为了做到这一点,你必须“导入”你的Person类,以便NHibernate知道它,你将不得不使用ResultTransformer。

像这样的东西:

 ICriteria crit = session.CreateCriteria (typeof(Person)); // set some filter criteria crit.SetProjection (Projections.ProjectionList() .Add (Property("Name"), "Name") .Add (Property( ... ) ); crit.SetResultTransformer(Transformers.AliasToBean(typeof(PersonView)); return crit.List(); 

但是,这仍然意味着您必须导入该类,以便NHibernate知道它。

通过使用这个类,NHibernate基本上会猜测所涉及的一切,包括你打算用于Person的表和字段映射。 NHibernate可能会被黑客攻击基于匹配名称或事物进行动态绑定,但整个想法是使用xml文件创建从普通旧数据对象到数据库字段的映射。

如果没有一个非常好的理由不映射该类,只需添加映射将为您提供最佳结果……

也就是说,您不能使用命名查询直接将结果注入未映射的类。 您需要告诉它将哪些列放入哪些字段,或者换句话说,映射。 ;)但是,您可以从命名查询返回标量值,您可以获取这些对象数组并手动构建集合。

为了解决这个问题,我最终使用了TupleToPropertyResultTransformer并提供了属性值列表。 这有一些限制,主要的一点是SQL查询必须以与向TupleToPropertyResultTransformer构造函数提供属性相同的顺序返回结果。

此外,属性类型是推断的,所以你需要小心十进制列只返回整数值等。除了使用TupleToPropertyResultTransformer提供了一个相当简单的方法来使用SQL查询返回一个对象集合而无需显式映射NHibernate中的对象。