NHibernate返回同一行的4个实例,而不是唯一的行

时间:2011-03-31 10:35:21

标签: c# nhibernate

背景

我对这个NHibernate查询的结果感到有点困惑:

var result = (List<RatingsLipper>)_session.CreateCriteria<RatingsLipper>()
                      .Add<RatingsLipper>(xx => xx.ShareClassId == shareClassId)
                      .List<RatingsLipper>();

其中RatingsLipper具有以下映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="FTMS.Domain"
                   namespace="FTMS.Domain.Entities">

    <class mutable="false" name="RatingsLipper" table="LipperRating" schema="offline">

        <id name="Id" column="LipperRating_LipperId">
            <generator class="native"></generator>
        </id>

        <property name="ShareClassId" column="LipperRating_ShareClassId" />

        <property name="RatingDate" column="LipperRating_RatingDate" />
        <property name="TimePeriod" column="LipperRating_RatingTimePeriodYears" />
        <property name="TotalReturn" column="LipperRating_TotalReturn" />
        <property name="ConsistentReturn" column="LipperRating_ConsistentReturn" />
        <property name="Preservation" column="LipperRating_Preservation" />
        <property name="Expense" column="LipperRating_Expense" />

    </class>
</hibernate-mapping>

该查询生成以下SQL:

SELECT this_.LipperRating_LipperId             ,
       this_.LipperRating_ShareClassId         ,
       this_.LipperRating_RatingDate           ,
       this_.LipperRating_RatingTimePeriodYears,
       this_.LipperRating_TotalReturn          ,
       this_.LipperRating_ConsistentReturn     ,
       this_.LipperRating_Preservation         ,
       this_.LipperRating_Expense              
FROM   offline.LipperRating this_
WHERE  this_.LipperRating_ShareClassId = 19278 /* @p0 */

反过来产生这个表:

LipperRating_LipperId LipperRating_ShareClassId LipperRating_RatingDate LipperRating_RatingTimePeriodYears LipperRating_TotalReturn LipperRating_ConsistentReturn LipperRating_Preservation LipperRating_Expense
--------------------- ------------------------- ----------------------- ---------------------------------- ------------------------ ----------------------------- ------------------------- --------------------
60011179              19278                     2011-02-28 00:00:00.000 3                                  3                        2                             4                         0
60011179              19278                     2011-02-28 00:00:00.000 5                                  3                        3                             5                         0
60011179              19278                     2011-02-28 00:00:00.000 10                                 5                        4                             5                         0
60011179              19278                     2011-02-28 00:00:00.000 99                                 4                        4                             4                         0

问题

我遇到的问题是我从NHibernate查询获得的结果包含第一行的4个实例,而不是我们在SQL查询的表格输出中看到的4个不同结果。

这是否与表LipperRating具有复合主键的事实有关?作为参考,该表定义为:

CREATE TABLE [offline].[LipperRating](
    [LipperRating_ShareClassId] [int] NOT NULL,
    [LipperRating_LipperId] [int] NOT NULL,
    [LipperRating_RatingDate] [datetime] NOT NULL,
    [LipperRating_RatingTimePeriodYears] [int] NOT NULL,
    [LipperRating_TotalReturn] [int] NULL,
    [LipperRating_ConsistentReturn] [int] NULL,
    [LipperRating_Preservation] [int] NULL,
    [LipperRating_Expense] [int] NULL,
 CONSTRAINT [LipperRatings_PK] PRIMARY KEY CLUSTERED 
(
    [LipperRating_ShareClassId] ASC,
    [LipperRating_LipperId] ASC,
    [LipperRating_RatingDate] ASC,
    [LipperRating_RatingTimePeriodYears] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

问题

我需要做些什么才能将正确的结果输入我的List<RatingsLipper>

1 个答案:

答案 0 :(得分:7)

我在http://dotnetslackers.com/Community/blogs/antrad/archive/2008/02/10/how-to-map-composite-key-in-nhibernate.aspx

的帮助下弄明白了

我需要<composite-id>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="FTMS.Domain"
                   namespace="FTMS.Domain.Entities">

    <class mutable="false" name="RatingsLipper" table="LipperRating" schema="offline">
        <composite-id>
            <key-property name="Id" column="LipperRating_LipperId" />
            <key-property name="ShareClassId" column="LipperRating_ShareClassId" />
            <key-property name="RatingDate" column="LipperRating_RatingDate" />
            <key-property name="TimePeriod" column="LipperRating_RatingTimePeriodYears" />
        </composite-id>

        <property name="TotalReturn" column="LipperRating_TotalReturn" />
        <property name="ConsistentReturn" column="LipperRating_ConsistentReturn" />
        <property name="Preservation" column="LipperRating_Preservation" />
        <property name="Expense" column="LipperRating_Expense" />
    </class>
</hibernate-mapping>

我还必须将其添加到我的RatingsLipper类型:

public override bool Equals(object obj)
{
    bool equals = false;

    if (null != obj)
    {
        RatingsLipper temp = obj as RatingsLipper;
        if (null != temp)
        {
            equals = (this.ShareClassId == temp.ShareClassId 
                && this.TimePeriod.Equals(temp.TimePeriod) 
                && this.Id.Equals(temp.Id)
                && this.RatingDate.Equals(temp.RatingDate));
        }
    }

    return equals;
}

public override int GetHashCode()
{
    int hash = 1122; // no idea of the significance of this number!

    hash += (this.ShareClassId.GetHashCode());
    hash += (this.TimePeriod.GetHashCode());
    hash += (this.Id.GetHashCode());
    hash += (this.RatingDate.GetHashCode());

    return hash;
}