当我在学习使用NHibernate Mapping Attribute的时候,遇到复合主键映射问题,查询了很多资料,也向朋友请教过,由于相关资料不多,中间走了些弯路,好在最终较好解决了,现记录分享如下:
一、环境:vs2019,
问题一:
因为ISession().Get<T>(object)方法,只有一个参数,当我们使用这个方法的时候,因为映射的数据表主键是复合主键,应该是多个参数;有时候我们可能觉得,这样做不是必要的,因为我们可以使用很多其他的NHibernate所支持的Query方法,但是我们有几个问题需要考虑,我们的代码可能给其他同事修改,我们要保证代码完整性,确保ISession().Get<T>(object)方法能使用,还有如果我们把NHibernate执行的sql语句显示出来会发现其他query方法跟ISession().Get<T>(object)方法是不一样的,还有我们获取实体对象的一般方法都是通过主键,等等原因吧,这时候这样做的必要性就体现出来了;
解决办法:
1)、定义复核主键类;
2)、此类中有且只有所有的主键字段属性
3)、重写Equals()和GetHashCode()两个方法;
4)、复核主键类必须可序列化,也就是需要[Serializable]特性;
5)、使用NHibernate Mapping Attribute的特性映射所有属性;
[Serializable]
public class PaiVisitEmpPK
{
[CompositeId(0, Name = "ID", ClassType = typeof(PaiVisitEmpPK))]
[KeyProperty(1, TypeType = typeof(string), Column = "SERIALNO", Name = "Serialno")]
[KeyProperty(2, TypeType = typeof(short), Column = "ROWNO", Name = "Rowno")]
public virtual string Serialno { get; set; }
public virtual short Rowno { get; set; }
public override int GetHashCode() => (Serialno + "|" + Rowno).GetHashCode();
public override bool Equals(object obj)
{
if (typeof(PaiVisitEmpPK) != obj.GetType())
return false;
var o = obj as PaiVisitEmpPK;
if (o.Serialno != Serialno)
return false;
if (o.Rowno != Rowno)
return false;
return true;
}
}
问题二&#