开发者

how to delete fk children in nhibernate

开发者 https://www.devze.com 2023-01-01 22:31 出处:网络
I would like to delete the ICollection PriceBreaks from Product. I\'m using the following method. However they dont seem to delete. What am i missing.

I would like to delete the ICollection PriceBreaks from Product.

I'm using the following method. However they dont seem to delete. What am i missing. When i step thru. i notice that "product.PriceBreaks.Clear();" doesn't actually clear the items. Do i need to flush or something?

public 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?
}

}

Here are my hbm files

  <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=开发者_StackOverflow"ProductId"  not-null="true"  class="EStore.Domain.Model.Product, EStore.Domain" />    
  </class>

My Entities

 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; }  
    }

Here is the sql from nhprof

// SELECT product0_.Id as Id0_0_ FROM Products product0_ WHERE product0_.Id = 23 /* @p0 */

and then

SELECT pricebreak0_.ProductId as ProductId1_, pricebreak0_.Id as Id1_, pricebreak0_.Id as Id1_0_, pricebreak0_.ProductId as ProductId1_0_, FROM PriceBreaks pricebreak0_ WHERE pricebreak0_.ProductId = 23 /* @p0 */

there is no update or select


Product probably needs to be associated with that session. It looks like you are trying to save a detached object. Which means there is no session to track that call to clear the PriceBreaks. Change it to this...

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();
    }
}

or move the session and transaction management further up. Which would basically eliminate the need for this method.


Have you tried deleting the cascade="all" on the PriceBreak side ?

Have you tried using session.Save() instead of SaveOrUpdate() ?

0

精彩评论

暂无评论...
验证码 换一张
取 消