我有一个带有多个细节线的标题的简单对象模型。我已经将header对象的bag属性映射到了line类,并在line类上放置了header属性来设置双向关系。
当我运行我的测试时,使用NHibernate Profiler我可以看到正在执行查询,并且从数据库中获取标题和行,但该集合始终为空。
当我直接查询行对象的集合时,我可以得到它们并看到正确填充了标题对象,所以我知道映射可能没问题。
稍微不符合标准的方面是线对象具有复合键。 (这是一个遗留数据库,我不能改变这个),所以我想知道这是不是问题。
这是我的类和映射(简化)
<class name="Header" table="HEADER">
<id name="ID" column="HEAD_ID">
<generator class="assigned" />
</id>
<bag name="Lines" table="BODY" order-by="BODY_LINE">
<key column="BODY_HEADER_ID"/>
<one-to-many class="Line"/>
</bag>
</class>
<class name="Line" table="BODY">
<composite-id>
<key-property name="ID" column="BODY_HEADER_ID"/>
<key-property name="Line" column="SBODY_LINE"/>
</composite-id>
<many-to-one class="Header" name="Head" column="BODY_HEADER_ID" />
</class>
public class Header {
public virtual string ID { get; set; }
public virtual IList<Line> Lines { get; set; }
}
public class Line {
public virtual string ID { get; set; }
public virtual int Line { get; set; }
public virtual Header Head { get; set; }
public override bool Equals(object obj) {
var other = obj as Line;
return ID == other.ID && Line == other.Line;
}
public override int GetHashCode() {
return (ID + "|" + Line.ToString()).GetHashCode();
}
}
我可以通过分别查询Line对象来解决这个问题,但我想知道我做错了什么。
编辑:好的,当我简化了一些事情时,我没有做到这一点。对困惑感到抱歉。我已经更改了映射和类定义,以更准确地反映事物。
答案 0 :(得分:3)
您要将同一列映射两次(BODY_HEADER_ID),并为HEADER表使用不同的三个不同的类名。
这是正确的线路映射:
<class name="Line" table="BODY">
<composite-id>
<key-many-to-one class="Header" name="Header" column="BODY_HEADER_ID"/>
<key-property name="Line" column="SBODY_LINE"/>
</composite-id>
</class>
当然,Line应该只有对Header的单一引用。