我有一个模型包含与多对多关系相同模型的列表,当与另一个项目有关系时删除此模型类型的项目时出现问题。
由于外键错误而发生此错误。
型号代码如下:
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();
答案 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
键,而不是外键...