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;
}
精彩评论