开发者

NHibernate is returning 4 instances of the same row, rather than unique rows

Background

I'm a bit confused by the result I'm getting from this NHibernate query:

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

where RatingsLipper has the following mapping:

<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>

The query produces the following 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 */

which in turn produces this table:

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

The Problem

the problem I'm having is that the result I'm getting from the NHibernate query consists of 4 instances of the first row, and not the 4 different results we see in the tabular output from the SQL query.

Does this have something to do with the fact that the table LipperRating has a composite primary key? For reference, this table is defined as:

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  = OF开发者_开发知识库F, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

The Question

What do I need to do to get the correct results into my List<RatingsLipper>?


I figured it out, with the help of: http://dotnetslackers.com/Community/blogs/antrad/archive/2008/02/10/how-to-map-composite-key-in-nhibernate.aspx

I needed <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>

and I also had to add this to my RatingsLipper type:

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜