代码之家  ›  专栏  ›  技术社区  ›  frosty

如何删除nhibernate中的fk子项

  •  1
  • frosty  · 技术社区  · 16 年前

    我想从产品中删除ICollection Pricebreaks。

    我使用以下方法。但是他们似乎没有删除。我错过了什么。 当我跨过。我注意到“product.pricebreaks.clear();”实际上并没有清除项目。我需要冲水还是什么?

    公共void removepricebreak(int productid) {

    using (ISession session = EStore.Domain.Helpers.NHibernateHelper.OpenSession())
    using (ITransaction transaction = session.BeginTransaction())
    {
        var product = session.Get<Product>(productId); 
       // i can see 20 PriceBreak records, tho nh prof saids PriceBreak table hasn't been hit
        product.PriceBreaks.Clear();
        session.SaveOrUpdate(product);
        transaction.Commit(); // PriceBreak table is hit here with select statement, no delete?
    }
    

    }

    这是我的HBM档案

      <class name="Product" table="Products">
        <id name="Id" type="Int32" column="Id" unsaved-value="0">
          <generator class="identity"/>
        </id>
        <property name="CompanyId" column="CompanyId" type="Int32" not-null="true" />
        <property name="Name" column="Name"/>
        <set name="PriceBreaks" table="PriceBreaks" generic="true" cascade="all-delete-orphan" inverse="true" >
          <key column="ProductId" />
          <one-to-many class="EStore.Domain.Model.PriceBreak, EStore.Domain" />
        </set>    
      </class>
    
    
    
    <class name="PriceBreak" table="PriceBreaks">
        <id name="Id" type="Int32" column="Id" unsaved-value="0">
          <generator class="identity"/>
        </id> 
        <many-to-one name="Product" column="ProductId"  not-null="true"  class="EStore.Domain.Model.Product, EStore.Domain" />    
      </class>
    

    我的实体

     public class Product
        {
    
            public virtual int Id { get; set; }
        public virtual ICollection<PriceBreak> PriceBreaks { get; set; }
            public virtual void AddPriceBreak(PriceBreak priceBreak)
            {
                priceBreak.Product = this;
                PriceBreaks.Add(priceBreak);
            }
        }
    
    
    
    
     public class PriceBreak
        {
            public virtual int Id { get; set; }
            public virtual Product Product { get; set; }  
        }
    

    这是NHPROF的SQL

    / / 选择product0_u.id作为id0_0_ 来自产品产品0_ 其中,product0_.id=23/*@p0*/

    然后

    选择pricebreak0_.productid作为productid1_u, pricebreak0_.id为id1_uuu, pricebreak0_.id作为id1_0_, pricebreak0_.productid作为productid1_0_, 从价格突破价格突破0_ 其中pricebreak0_.productid=23/*@p0*/

    没有更新或选择

    2 回复  |  直到 16 年前
        1
  •  1
  •   dotjoe    16 年前

    产品可能需要与该会话关联。看起来您正在尝试保存分离的对象。这意味着没有任何会话可以跟踪该呼叫以清除价格突破。把它改成这个…

    public void RemovePriceBreak(int productId)
    {
    
        using (ISession session = EStore.Domain.Helpers.NHibernateHelper.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            var product = session.Get<Product>(productId);
            product.PriceBreaks.Clear();
            session.SaveOrUpdate(product);
            transaction.Commit();
        }
    }
    

    或者进一步向上移动会话和事务管理。基本上不需要这种方法。

        2
  •  1
  •   mathieu    16 年前

    你试过删除Pricebreak端的cascade=“all”吗?

    是否尝试使用session.save()而不是saveorupdate()?

    推荐文章