2012-07-10 63 views
0

在NHibernate中,我定义了一个类及其映射。我不确定复合键定义和equals/GetHashCode是否正确?NHibernate复合键问题

[DataMember] 
public virtual int EXCEPTION_ID { get; set; } 

[DataMember] 
public virtual int RUNID { get; set; } 

[DataMember] 
public virtual int ROW_ID { get; set; } 

[DataMember] 
public virtual string FIELD_NAME { get; set; } 

[DataMember] 
public virtual string FIELD_VALUE { get; set; } 

public override bool Equals(object obj) 
{ 
    if (obj == null) 
    { 
     return false; 
    } 

    var t = obj as ExceptionFld; 

    if ((EXCEPTION_ID == t.EXCEPTION_ID) && (RUNID == t.RUNID) && (ROW_ID == t.ROW_ID) && (FIELD_NAME == t.FIELD_NAME)) 
    { 
     return true; 
    }  

    return false; 
}   

public override int GetHashCode() 
{ 
    return (EXCEPTION_ID + "|" + RUNID + "|" + ROW_ID + "|" + FIELD_NAME).GetHashCode(); 
} 

映射文件是

<composite-id> 
     <key-property name="EXCEPTION_ID"/> 
     <key-property name="RUNID"/> 
     <key-property name="ROW_ID"/> 
     <key-property name="FIELD_NAME"/> 
    </composite-id> 

    <property name="EXCEPTION_ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" not-null="true"> 
     <column name="EXCEPTION_ID" /> 
    </property> 

    <property name="RUNID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" not-null="true"> 
     <column name="RUNID" /> 
    </property> 

    <property name="ROW_ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" not-null="true"> 
     <column name="ROW_ID" /> 
    </property> 

    <property name="FIELD_NAME" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" not-null="true"> 
     <column name="FIELD_NAME" /> 
    </property> 

    <property name="FIELD_VALUE" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" not-null="true"> 
     <column name="FIELD_VALUE" /> 
    </property> 
+0

你不确定它是否正确?一目了然,它看起来不错。你有没有试过它? – hometoast 2012-07-10 18:45:41

+0

我们是否必须创建一个单独的类来映射组合键? – user595234 2012-07-10 18:57:59

回答

0

从我所收集,你应该重新声明composite-id标签以外的属性(见example)。

我已经重写的Equals实现,像这样:

public override bool Equals(object obj) 
{ 
    var t = obj as ExceptionFld; 

    if (t == null) return false; 

    return EXCEPTION_ID == t.EXCEPTION_ID 
     && RUNID == t.RUNID 
     && ROW_ID == t.ROW_ID 
     && FIELD_NAME == t.FIELD_NAME; 
} 

,因为我确信你当前的实现将抛出时调用这样的NullReferenceException:

var instance = new ExceptionFld(); 
instance.Equals(""); 

当它真正应该只是返回false。

as运营商将尝试从string转换为ExceptionFld,注意投射失败,t将为空。

我不确定您的GetHashCode关于性能或散列码分布,但除此之外,它看起来可行。

+0

您可能想要在投射之前检查它是否为空。如果'obj'为null,那么演员将会抛出一个异常。 – 2012-07-10 19:53:04

+1

这不是事实。尝试运行'object nullRef = null; MyClass test = nullRef as MyClass;'看看会发生什么。现在,它*有可能是括号转换操作符最终可能会调用一些用户定义的转换,它将在null上失败,但'as'永远不会这样做。 – Rytmis 2012-07-10 20:04:34