Reputation: 631
I have a model contains a list of the same model as a many-to-many relationship, and I have a problem when deleting an item of this model type when having a relation with another item.
This error happened because of a foreign key error.
The model code is as the following:
public class Employee : ModelBase
{
public virtual string FullName { get; set; }
public virtual IList<Employee> Managers { get; set; }
}
The mapping file is as follows
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Models"
namespace="Models"
default-lazy="false">
<class name="Employee">
<id name ="Id">
<generator class="native" />
</id>
<property name="FullName"></property>
<bag name="Managers">
<key column="Id" />
<many-to-many class="Employee"/>
</bag>
</class>
</hibernate-mapping>
Suppose I have created two employees, emp1, emp2, and then I have added emp2 to Managers list in emp1.
If I want to delete emp1, I have the same error, but I can easily resolve it by clearing the managers list. but if I want to delete emp2, I cannot loop for every employee to see if the Managers list contains this employee!! it will reduce the performance.
My Question, is there an implicit way for nhibernate to handle this issue?
EDIT1 :
My delete statement is
var queryString = string.Format("delete {0} where Id = :id",
typeof(T));
session.CreateQuery(queryString)
.SetParameter("id", modelId)
.ExecuteUpdate();
Upvotes: 1
Views: 59
Reputation: 123861
Well, either we've got here the parent-child hierarchy, (x)or many-to-many relation.
I. In case of many-to-many, we are missing
The model we have is providing the up view: Managers
, and should also provide the down view: Subordinates
.
<bag name="Managers" table="ManagerSubOrdinates" >
<key column="ManagerId" />
<many-to-many class="Employee" column="SubordinateId"/>
</bag>
<bag name="Subordinates" table="ManagerSubOrdinates" inverse="true" >
<key column="SubordinateId" />
<many-to-many class="Employee" column="ManagerId"/>
</bag>
Now, we mapped both ends of the pairing table/relation ManagerSubOrdinates
. If we will delete the Employee, the related records will be removed as well - but just from the pairing table. Not the related Managers or Subordinates
Finally the Deletion.
Now, when we do have the mapping in place, the correct way how to delete is like this
// load the Employee with ID == 1 into the ISession
var employee = session.Get<Employee>(1); // id 1
// pass this instance into the Delete
session.Delete(employee);
This will instruct NHibernate to properly remove all records from pairing table (both mappings) and then delete the Employee record itself
(not sure here) II. If this is in fact, the parent-child relation, we have to correct the mapping this way:
<bag name="Subordinates">
<key column="ManagerId" />
<many-to-many class="Employee"/>
</bag>
<many-to-one class="Employee" Name="Manager" column="ManagerId" >
Here I am just guessing (more Subordinates, one Manager), but The essence is in the column name ManagerId
. In most scenarios, the key
column does not have value "Id" which usually referes to the table Primary
key, not the foreign key...
Upvotes: 1