虽然我意识到Set或Bag可能是正确的方法,但我是NHibernate的新手,我正在努力理解为什么会发生以下情况。
我有两个班级:
public class Customer
{
public virtual int Id { get; protected set; }
public virtual string CustomerName { get; set; }
// Customer has many domains
public virtual IList<Domain> Domains { get; set; }
}
public class Domain
{
public virtual int Id { get; protected set; }
public virtual int CustomerID { get; set; }
public virtual string DomainName { get; set; }
}
我的映射文件如下所示:
<!-- Domain -> tblDomains -->
<class name="Domain" table="tblDomains">
<id name="Id">
<column name="DomainID" sql-type="int" not-null="true"/>
<generator class="identity"/>
</id>
<property name="CustomerID"/>
<property name="DomainName"/>
</class>
<!-- Customer -> tblCustomer -->
<class name="Customer" table="tblCustomer">
<id name="Id">
<column name="CustomerID" sql-type="int" not-null="true"/>
<generator class="identity"/>
</id>
<property name="CustomerName" column="Customer"/>
<list name="Domains">
<key column="CustomerID"/>
<index column="DomainID"/>
<one-to-many class="Domain" />
</list>
</class>
当我检索Customer
对象时,Domains
属性包含665383个空Domain
个对象的列表。列表中的第665384项包含有效的填充对象。
这个客户只有63 Domain
个,所以我猜这是某种笛卡尔积的结果。我在NHProfiler中查看了SQL,但是当我遍历Domains
列表中的第一项时,我看到的是一个看起来相当无辜的查询:
SELECT domains0_.CustomerID as CustomerID1_,
domains0_.DomainID as DomainID1_,
domains0_.DomainID as DomainID2_0_,
domains0_.CustomerID as CustomerID2_0_,
domains0_.DomainName as DomainName2_0_
FROM tblDomains domains0_
WHERE domains0_.CustomerID = 5667 /* @p0 */
如果我使用<bag>
这一切都很好。谁能解释发动机罩下发生了什么?
答案 0 :(得分:2)
使用列表映射,索引将应用于列表中的对象集。也就是说,如果客户有一组63个域,那么通常该列表将包含0到62之间的值,以指示该客户的域集中的域对象的索引。
您已将索引设置为DomainId,即表的主键,这会造成严重破坏。我猜想Domain表总共有665384行(如果DomainId没有以1开头并且有间隙,则会更少),但我认为63表示有效而不是一行。你有没有检查过它们? : - )