Nhibernate 返回子类时,HQL查询结果“不能在此泛型集合中使用”

Nhibernate 返回子类时,HQL查询结果“不能在此泛型集合中使用”,nhibernate,hql,Nhibernate,Hql,鉴于以下情况: 公司拥有一系列产品对象。 区域具有产品对象的集合。 任何给定的产品都有一个公司和一个区域。 SpecialProduct是Product的一个子类 我在NHibernate中使用以下HQL查询 // return all SpecialProperty objects for a given company and area. IQuery query = session.CreateQuery("select product from Company as company "

鉴于以下情况:

公司拥有一系列产品对象。 区域具有产品对象的集合。 任何给定的产品都有一个公司和一个区域。 SpecialProduct是Product的一个子类

我在NHibernate中使用以下HQL查询

// return all SpecialProperty objects for a given company and area.
IQuery query = session.CreateQuery("select product from Company as company " +
    "join company.Products as product " +
    "join product.Area as area " +
    "where company.Id = :coId " +
    "and area.Id = :arId " +
    "and product.class = MyNamespace.DomainModel.SpecialProduct ")
    .SetInt64("coId", companyId)
    .SetInt64("arId", areaId);
IList<SpecialProduct> specialProducts = query.List<SpecialProduct>();
当执行上面的第二条语句时,我得到一个错误,指出:

无法执行查询[SQL:SQL不可用] SpecialProduct值的类型不是MyNamespace.DomainModel.SpecialProduct,因此不能在此泛型集合中使用。 参数名称:value

请注意,由于SpecialProduct类中存在ToString重写,因此上述消息中的对象显示为SpecialProduct

如果我更改语句以返回超类、产品的列表,就像这样

IList<Product> products = query.List<Product>();  
…然后我没有得到错误,列表中返回了一个匹配的对象。在调试器中检查这个对象,我看到它实际上是一个特殊的产品,根据ToString覆盖,但仔细观察,我发现它是一个NHibernate代理类。如果我尝试将对象强制转换为SpecialProduct,则强制转换失败。嗯

我还检查了数据库本身,并确认该记录已保存为SpecialProduct,这是因为在联接的子类表中存在匹配的记录

我需要将结果作为SpecialProperty对象的通用集合来获取


你知道为什么这不起作用吗?

这是设计出来的。NH代理继承自基类型,而不是子类


希望能有所帮助。

这是设计的。NH代理继承自基类型,而不是子类


希望能有所帮助。

问题突然消失了。由于代码中其他地方的一些更改,查询没有更改,查询现在返回的是类的实际实例,而不是类的NHibernate代理。想想看吧如果知道它为什么开始返回实际对象而不是代理,以防再次发生这种情况,那就太好了-这个问题突然消失了。由于代码中其他地方的一些更改,查询没有更改,查询现在返回的是类的实际实例,而不是类的NHibernate代理。想想看吧如果知道它为什么开始返回实际对象而不是代理,以防再次发生这种情况,那就太好了-谢谢你的联系,迭戈。通过使用引用基类型的属性从另一个对象遍历到达的代理不能直接转换为子类型,这是有道理的。然而,在我的情况下,引用位于HQL查询中,该查询还限制返回类型…product.class=子类型。换句话说,我给NH提供了足够的信息,让它提前知道应该返回的类型。此外,我要求作为查询结果的子类型列表,而不是引用它们的对象列表。有没有一种方法可以指示NH返回子类型?也许可以使用CreateCriteria来代替?类似于session.CreateCriteriatypeofSpecialProperty…列表;也许吧?@MylesRip:不。最好的情况是,它有时会在那里工作,一旦你在会话中加载了该实例的代理,它就会严重崩溃。这太糟糕了。我希望找到一个可以在NHibernate查询时应用的解决方案。我想我唯一的方法就是根据需要使用后门,如上面链接所述。谢谢你的帮助!谢谢你的链接,迭戈。通过使用引用基类型的属性从另一个对象遍历到达的代理不能直接转换为子类型,这是有道理的。然而,在我的情况下,引用位于HQL查询中,该查询还限制返回类型…product.class=子类型。换句话说,我给NH提供了足够的信息,让它提前知道应该返回的类型。此外,我要求作为查询结果的子类型列表,而不是引用它们的对象列表。有没有一种方法可以指示NH返回子类型?也许可以使用CreateCriteria来代替?类似于session.CreateCriteriatypeofSpecialProperty…列表;也许吧?@MylesRip:不。最好的情况是,它有时会在那里工作,一旦你在会话中加载了该实例的代理,它就会严重崩溃。这太糟糕了。我希望找到一个可以在NHibernate查询时应用的解决方案。我想我唯一的方法就是根据需要使用后门,如上面链接所述。谢谢你的帮助!