nhibernate sql-query结果与直接查询结果不同

时间:2009-12-07 15:07:32

标签: nhibernate stored-procedures sql

更新:我已在下面回答了我的问题,请先了解并告诉我您是否有更好的方法


执行摘要:
当从SQL Management Studio调用我的sqlserver函数时,我得到一个结果为{1,2,3}的列表。 当使用NHibernate从代码调用方法时,我得到这个列表{1,1,1}。 ('1'是整个结果行,而不是标量'1') 我也用不同的数据集尝试了它并得到了相同的行为。

长篇故事:
我在sql server中有一个sql函数,名为GetHistory(itemId)。它返回一个包含结果的表。 当我从SQL Management Studio查询时,我得到一个结果列表。我通过调用函数来查询:

select * from GetHistory(10001)

在我给定的数据库上,这会产生3行。每一行都有时间,类型和描述 在NHibernate中,我特别为此创建了一个新实体,因为没有这样的有机表/实体。 所以我有一个映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
 namespace="myNamespace" assembly="myAssembly">
 <class name="HistoryEvent">
 <id name="id" type="long" access="field">
  <column name="Id"/>
  <generator class="native"/>
 </id>
 <property name="type" column="Type" type="short" access="field"/>
 <property name="time" column="Time" type="datetime" access="field"/>
 <property name="description" column="Description" type="string" access="field"/>
</class>

<sql-query name='GetHistory'>
    <return class='HistoryEvent, myAssembly' alias='historyEvent'/>
 <![CDATA[SELECT * FROM GetHistory(:id)]]>
</sql-query>
</hibernate-mapping>

业务对象如下所示:

 public class HistoryEvent
 {
     private long id;
  private short type;
  private string description;
  private DateTime time;
        ... here be properties with public getter etc...
    }

最后,我从我的代码中调用此函数,如下所示:

IList result = s.GetNamedQuery("GetHistory").SetInt64("id", id).List();

使用调试器检查此列表时,我得到3个同一行3次的实体。 我也尝试直接从NHibernate使用查询(使用sql-query)而不是通过数据库函数,但得到了相同的结果。
我的直觉是我的映射有问题,或NHibernate有问题:)
帮助!

1 个答案:

答案 0 :(得分:0)

好的,在我发布问题后不久,我想出来了。
写这样的一切真的对我有帮助。这就是问题:
我使用的Id列并不是唯一的。它是一个ID,而不是查询的正确ID。这是为什么?因为我的查询返回来自三个不同表的三个查询的并集,并且返回的ID实际上是ItemId(传递给函数的同一个!)

所以现在我必须有一个唯一的ID。我曾尝试使用NHibernate的复合id标签而不是id - 但面对困难我决定不再浪费更多时间在自动化的东西上并从查询中返回ID。

发现我无法使用SELECT IDENTITY()INTO ...内部函数与表变量,我考虑兰德一秒钟,并最终使用ROW_NUMBER()OVER(SORT BY blah)生成我的假身份证。 目前这种方法效果很好,虽然这段代码不会赢得选美比赛。
PS:有更好的方法来生成ID吗?或者你有没有得到复合ID来为你工作?让我知道......