【发布时间】:2010-12-26 01:46:02
【问题描述】:
我的应用中有 3 个顶级实体:电路、问题、文档
Circuits 可以包含 Documents,Issue 可以包含 Documents。
当我删除一个电路时,我希望它删除与之关联的文档,除非它被其他人使用。我希望对问题有同样的行为。当唯一的关联在数据库中的同一个表中时,我让它工作,但如果它在另一个表中,那么它会由于外键约束而失败。
ex 1(这将正确级联,因为从电路到文档只有一个外部约束)
Document1 存在。
Circuit1 存在并包含对 Document1 的引用。
如果我删除 Circuit1,那么它会同时删除 Document1。
ex 2(这将正确级联,因为从电路到文档只有一个外部约束。)
Document1 存在。
Circuit1 存在并包含对 Document1 的引用。
Circuit2 存在并包含对 Document1 的引用。
如果我删除 Circuit1,那么它会被删除,但 Document1 不会被删除,因为 Circuit2 存在。
如果我随后删除 Circuit2,则 Document1 将被删除。
ex 3(这将引发错误,因为当它删除电路时,它会看到没有其他电路引用该文档,因此它会尝试删除该文档。但是它不应该,因为有一个对文档有外部约束的问题。)
文档 1 存在。
Circuit1 存在并包含对 Document1 的引用。
问题 1 存在并包含对 Document1 的引用。
如果我删除 Circuit1,那么它会失败,因为它会尝试删除 Document1,但 Issues1 仍然有参考。
数据库:
这个想法不会让上传图片,所以这里是数据库的 ERD:http://lh3.ggpht.com/_jZWhe7NXay8/TROJhOd7qlI/AAAAAAAAAGU/rkni3oEANvc/CircuitIssues.gif
型号:
public class Circuit
{
public virtual int CircuitID { get; set; }
public virtual string CJON { get; set; }
public virtual IList<Document> Documents { get; set; }
}
public class Issue
{
public virtual int IssueID { get; set; }
public virtual string Summary { get; set; }
public virtual IList<Model.Document> Documents { get; set; }
}
public class Document
{
public virtual int DocumentID { get; set; }
public virtual string Data { get; set; }
}
映射文件:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="Model">
<class name="Circuit" table="Circuit">
<id name="CircuitID">
<column name="CircuitID" not-null="true"/>
<generator class="identity" />
</id>
<property name="CJON" column="CJON" type="string" not-null="true"/>
<bag name="Documents" table="CircuitDocument" cascade="save-update,delete-orphan">
<key column="CircuitID"/>
<many-to-many class="Document">
<column name="DocumentID" not-null="true"/>
</many-to-many>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="Model">
<class name="Issue" table="Issue">
<id name="IssueID">
<column name="IssueID" not-null="true"/>
<generator class="identity" />
</id>
<property name="Summary" column="Summary" type="string" not-null="true"/>
<bag name="Documents" table="IssueDocument" cascade="save-update,delete-orphan">
<key column="IssueID"/>
<many-to-many class="Document">
<column name="DocumentID" not-null="true"/>
</many-to-many>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="Model">
<class name="Document" table="Document">
<id name="DocumentID">
<column name="DocumentID" not-null="true"/>
<generator class="identity" />
</id>
<property name="Data" column="Data" type="string" not-null="true"/>
</class>
</hibernate-mapping>
代码:
using (ISession session = sessionFactory.OpenSession())
{
var doc = new Model.Document() { Data = "Doc" };
var circuit = new Model.Circuit() { CJON = "circ" };
circuit.Documents = new List<Model.Document>(new Model.Document[] { doc });
var issue = new Model.Issue() { Summary = "iss" };
issue.Documents = new List<Model.Document>(new Model.Document[] { doc });
session.Save(circuit);
session.Save(issue);
session.Flush();
}
using (ISession session = sessionFactory.OpenSession())
{
foreach (var item in session.CreateCriteria<Model.Circuit>().List<Model.Circuit>())
{
session.Delete(item);
}
//this flush fails, because there is a reference to a child document from issue
session.Flush();
foreach (var item in session.CreateCriteria<Model.Issue>().List<Model.Issue>())
{
session.Delete(item);
}
session.Flush();
}
【问题讨论】:
标签: c# nhibernate many-to-many cascade