简体   繁体   中英

Nhibernate doesnt cascade delete

I have a very simple problem with nhibernate (I just started using it)

I have the following hbm mapping files :

<class name="Customer" table="Customers" lazy="false">
<id name="Id" column="CustomerId">
    <generator class="native">
</id>
<property name="Name" />
<property name="Picture" type="BinaryBlob" />
<bag name="Orders" cascade="all-delete-orphan" lazy="false">
  <key column="CustomerId" />
  <one-to-many class="Order" />
</bag>
</class>

<class name="Order" table="Orders" lazy="false">
<id name="Id" column="OrderId">
    <generator class="native">
</id>
<property name="Name" />
<property name="Picture" type="BinaryBlob" />
<bag name="Products" cascade="all-delete-orphan" lazy="false"
  <key column="OrderId" />
  <one-to-many class="Product" />
</bag>
</class>

<class name="Product" table="Products" lazy="false">
<id name="Id" column="ProductId">
    <generator class="native">
</id>
<property name="Name" />
<property name="Picture" type="BinaryBlob" />
<property name="ProductStr" />
</class>

Customer class has an int id, string name, byte[] picture and IList of Orders.

Order class has an int id, string name, byte[] picture and IList of Products.

Product class has an int id, string name, byte[] picture, string productstr and int quantity (which I dont currently use)

Customer table has a customer id, name and picture(varbinary(max)).

Order has order id, name, picture and a customer id

Product has a product id, name, picture, productstr and order id.

The problem : When I delete a customer using session.Delete(csCustomer), it succesfuly deletes the entire customer from the db but it doesnt delete all of its orders. It only puts null in the customer id field in all of the orders of the deleted customer.

Anyone can find a problem with my configuration? I saw an example of using nhibernate where they saved a reference to the customer in the order class and a reference to order in the product class, is that something I need to do to fix it?

You have to set inverse="true" on your bag.

Your Customer mapping should look like this:

<class name="Customer" table="Customers" lazy="false">
<id name="Id" column="CustomerId">
    <generator class="native">
</id>
<property name="Name" />
<property name="Picture" type="BinaryBlob" />
<bag name="Orders" cascade="all-delete-orphan" inverse="true" lazy="false">
  <key column="CustomerId" />
  <one-to-many class="Order" />
</bag>
</class>

There's a good article about this property here and Ayende has written about it long time ago.

I would suggest you to extend your Order mapping referencing your customer adding:

<many-to-one name="Customer" column="CustomerId" not-null="true"/>

and add the virtual property to your class:

public virtual Customer Customer { get; set; }

Some more information here .

Another thing you might want to consider is change the bag with a set cause as bag allows duplicates, as explained here .

And maybe strengthen your domain using encapsulation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM