删除其中包含多对多关系的项目

时间:2014-03-18 06:18:32

标签: nhibernate nhibernate-mapping

我有一个模型包含与多对多关系相同模型的列表,当与另一个项目有关系时删除此模型类型的项目时出现问题。

由于外键错误而发生此错误。

型号代码如下:

public class Employee : ModelBase
{
    public virtual string FullName { get; set; }

    public virtual IList<Employee> Managers { get; set; }

}

映射文件如下

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

假设我创建了两个雇员,emp1,emp2,然后我在emp1中将emp2添加到Managers列表。

如果我想删除emp1,我有同样的错误,但我可以通过清除管理器列表轻松解决它。但如果我想删除emp2,我不能为每个员工循环查看Managers列表是否包含该员工!它会降低性能。

我的问题,是否有一种隐含的方式让nhibernate处理这个问题?

EDIT1:

我的删除声明是

var queryString = string.Format("delete {0} where Id = :id",
    typeof(T));
session.CreateQuery(queryString)
    .SetParameter("id", modelId)
    .ExecuteUpdate();

1 个答案:

答案 0 :(得分:1)

嗯,要么我们在这里有父子层次结构,(x)或多对多关系。

予。在多对多的情况下,我们缺少

  • 配对表
  • 关于这种关系的第二个回归观点。

我们的模型提供了向上视图:Managers,还应提供向下视图: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>

现在,我们映射了配对表/关系ManagerSubOrdinates的两端。如果我们将删除Employee,相关记录也将被删除 - 但只是从配对表中删除。不是相关的经理或下属

最后是删除。

现在,当我们确实有映射时,正确的删除方法就像这样

// 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);

这将指示NHibernate正确删除配对表中的所有记录(两个映射),然后删除Employee记录本身

(不确定)II。如果这实际上是父子关系,我们必须以这种方式纠正映射:

<bag name="Subordinates">
  <key column="ManagerId" />
  <many-to-many class="Employee"/>
</bag>
<many-to-one class="Employee" Name="Manager" column="ManagerId" >

这里我只是猜测(更多的下属,一个经理),但本质是列名 ManagerId。在大多数情况下,key列没有值&#34; Id&#34; ,它通常引用表Primary键,而不是外键...