C# NHibernate添加到子集合会导致查询返回大量/过多的行

C# NHibernate添加到子集合会导致查询返回大量/过多的行,c#,nhibernate,C#,Nhibernate,我有一个问题,当我将对象添加到集合的子集合时,NHibernate会对集合中的所有子对象进行选择。这将导致NHProf中出现“返回的行数过多”警报,最后,如果集合中有足够的对象,则返回System.OutOfMemoryException 编辑:NHibernate版本为3.0.0 Beta 2 编辑2:通过将OrderPositions集合设置为一个包来解决此问题。如果需要一个集合,仍然会对如何避免如此昂贵的查询感兴趣 编辑3:再考虑一下。由于equality和getHash是在c#类中实现的

我有一个问题,当我将对象添加到集合的子集合时,NHibernate会对集合中的所有子对象进行选择。这将导致NHProf中出现“返回的行数过多”警报,最后,如果集合中有足够的对象,则返回System.OutOfMemoryException

编辑:NHibernate版本为3.0.0 Beta 2

编辑2:通过将OrderPositions集合设置为一个包来解决此问题。如果需要一个集合,仍然会对如何避免如此昂贵的查询感兴趣

编辑3:再考虑一下。由于equality和getHash是在c#类中实现的,NH可能无法确定它是否可以向集合中添加一个项,然后填充整个集合并尝试实际向集合中添加该项。仍然能够告诉NH如何确定hbm文件中的相等性,比如说自然id约束将非常好。这可能吗

这是我调用NHibernate时生成的查询 someOrder.AddOrderPosition(someOrderPosition)

以下是示例代码:

public class Order : Entity<int>
{
    private ISet<OrderPosition> orderPositions = new HashedSet<OrderPosition>();

    public virtual DateTime OrderDate { get; set; }

    public virtual ISet<OrderPosition> OrderPositions
    {
        get
        {
            return this.orderPositions;
        }

        protected set
        {
            this.orderPositions = value;
        }
    }

    public virtual void AddOrderPosition(OrderPosition orderPosition)
    {
        if (orderPosition.Order != null)
        {
            orderPosition.Order.OrderPositions.Remove(orderPosition);
        }

        orderPosition.Order = this;
        this.OrderPositions.Add(orderPosition);
    }
}


public class OrderPosition : Entity<int>
{
    public virtual int OrderedAmount { get; set; }

    public virtual Order Order { get; set; }

    public virtual Article Article { get; set; }
}


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="Order" table="Orders">
    <id name="Id" column="OrderId">
      <generator class="native" />
    </id>
    <set name="OrderPositions" inverse="true" cascade="all-delete-orphan">
      <key column="OrderId" />
      <one-to-many class="OrderPosition" />
    </set>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  assembly="DataTransfer" namespace="DataTransfer">
  <class name="OrderPosition" table="OrderPositions">
    <id name="Id" column="OrderPositionId">
      <generator class="native" />
    </id>
    <property name="OrderedAmount" />
    <many-to-one name="Order" column="OrderId" cascade="all" />
    <many-to-one name="Article" column="ArticleId" cascade="all" />
  </class>
</hibernate-mapping>
公共类顺序:实体
{
私有ISet orderPositions=new HashedSet();
公共虚拟日期时间OrderDate{get;set;}
公共虚拟ISet订单位置
{
得到
{
返回此.orderPositions;
}
保护集
{
this.orderPositions=值;
}
}
公共虚拟无效AddOrderPosition(OrderPosition OrderPosition)
{
if(orderPosition.Order!=null)
{
orderPosition.Order.OrderPositions.Remove(orderPosition);
}
orderPosition.Order=this;
this.OrderPositions.Add(orderPosition);
}
}
公共类OrderPosition:实体
{
公共虚拟int-OrderedAmount{get;set;}
公共虚拟订单{get;set;}
公共虚拟项目{get;set;}
}

尝试将未保存的值添加到OrderPositions映射上的
元素。例如:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  assembly="DataTransfer" namespace="DataTransfer">
  <class name="OrderPosition" table="OrderPositions">
    <id name="Id" column="OrderPositionId" unsaved-value="0">
      <generator class="native" />
    </id>
    <property name="OrderedAmount"
    <many-to-one name="Order" column="OrderId" cascade="all" />
    <many-to-one name="Article" column="ArticleId" cascade="all" />
  </class>
</hibernate-mapping>


正在尝试将未保存的值添加到OrderPositions映射上的
元素。例如:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  assembly="DataTransfer" namespace="DataTransfer">
  <class name="OrderPosition" table="OrderPositions">
    <id name="Id" column="OrderPositionId" unsaved-value="0">
      <generator class="native" />
    </id>
    <property name="OrderedAmount"
    <many-to-one name="Order" column="OrderId" cascade="all" />
    <many-to-one name="Article" column="ArticleId" cascade="all" />
  </class>
</hibernate-mapping>


问题是set和bag的语义。包是无序的物品集合,可能包含重复的物品。集合是没有重复项的无序项集合。因此,NHibernate必须对基于集合的子集合执行选择,以确保在保存之前不存在重复项。

问题在于集合和包的语义。包是无序的物品集合,可能包含重复的物品。集合是没有重复项的无序项集合。因此,NHibernate必须在基于集合的子集合上执行选择,以确保在保存之前不存在重复项。

添加未保存的值不会产生任何影响。但你让我思考。实体基类中的相等只查看id,而且在db(和域)中没有进一步的约束。因此,使用集合语义毫无意义。在这里使用袋子是正确的选择。这样也没有未绑定的查询。很高兴听到您已经解决了它。我不完全确定我的想法是否可行,但我很高兴听到它帮助我找到了实际的解决方案。谢谢,你知道它是怎样的,经常谈论它会有帮助。我仍然想知道如果我真的需要一个集合,NHibernate会怎么做,在两个多对一关联周围设置一个自然id并没有改变任何事情。我希望NH将where子句设置为“where OrderId=someOrderId&&ArticleId=someArticleId”,但实际情况并非如此。NHibernate将未保存的值默认为默认值(t),对于整数PKs,默认值为零(0)。这就是为什么它没有什么不同。添加一个未保存的值没有什么不同。但你让我思考。实体基类中的相等只查看id,而且在db(和域)中没有进一步的约束。因此,使用集合语义毫无意义。在这里使用袋子是正确的选择。这样也没有未绑定的查询。很高兴听到您已经解决了它。我不完全确定我的想法是否可行,但我很高兴听到它帮助我找到了实际的解决方案。谢谢,你知道它是怎样的,经常谈论它会有帮助。我仍然想知道如果我真的需要一个集合,NHibernate会怎么做,在两个多对一关联周围设置一个自然id并没有改变任何事情。我希望NH将where子句设置为“where OrderId=someOrderId&&ArticleId=someArticleId”,但实际情况并非如此。NHibernate将未保存的值默认为默认值(t),对于整数PKs,默认值为零(0)。这就是为什么它没有起作用。