我正在使用NHibernate的自定义命名查询,我希望返回Person对象的集合。 Person对象没有映射到NHibernate映射,这意味着我得到以下异常:
System.Collections.Generic.KeyNotFoundException: 给定的密钥没有出现在 字典。
创建Session时会抛出它,因为它在调用NHibernate.Cfg.Mappings.GetClass(String className)时找不到类名。这一切都是可以理解的,但我想知道是否有任何方法告诉NHibernate使用该类,即使我没有它的映射?
答案 0 :(得分:9)
你为什么不用:
query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));
它将使用列别名作为属性名称将查询中每列的数据插入Person对象属性。
答案 1 :(得分:2)
如何创建一个返回未映射类型实例的查询?
我认为米哈尔在这里有一个观点,也许你应该看看预测。 (至少,这是我认为你正在寻找的)。
您在某些映射类型上创建查询,然后,您可以将该查询“投影”到“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<PersonView>();
但是,这仍然意味着你必须import这个类,所以NHibernate知道它。
答案 2 :(得分:0)
通过使用这个类,NHibernate基本上会猜测所涉及的一切,包括你打算用于Person的哪个表,以及字段映射。 NHibernate可能会被黑客攻击基于匹配名称或东西进行动态绑定,但整个想法是使用xml文件创建从普通旧数据对象到数据库字段的映射。
答案 3 :(得分:0)
如果没有非常好的理由不映射课程,只需添加映射就可以获得最佳效果......
也就是说,您不能使用命名查询直接将结果注入未映射的类。您需要告诉它将哪些列放入哪些字段,或者换句话说,映射。 ;)但是,您可以从命名查询返回标量值,您可以获取这些对象数组并手动构建集合。
答案 4 :(得分:0)
为了解决这个问题,我最终使用了TupleToPropertyResultTransformer并提供了属性值列表。这有一些限制,主要的一点是SQL查询必须以与向TupleToPropertyResultTransformer构造函数提供属性相同的顺序返回结果。
此外,还推断了属性类型,因此您需要注意十进制列只返回整数值等。除了使用TupleToPropertyResultTransformer之外,还提供了一种使用SQL查询返回对象集合而无需显式映射的相当简单的方法NHibernate中的对象。