Many of many remove two parents with a common association in NHibernate

I have 3 top-level objects in my application: Circuit, Issue, Document

Schemes may contain documents, and problems may contain documents.

When I delete Circuit, I want it to delete documents associated with it, unless it is used by someone else. I would like it to be the same as with the problems. I work when the only association is in one table in db, but if it is in another table, then it fails due to foreign key constraints.

ex 1 ( This will be cascaded correctly, because there is a restriction only from Circuit to Document )
Document1 exists.
Circuit1 exists and contains a link to Document1.
If I delete Circuit1, then it will delete Document1 with it.

ex 2 ( This will be cascaded correctly because there is a restriction only from Circuit to Document. )
Document1 exists.
Circuit1 exists and contains a link to Document1.
Circuit2 exists and contains a link to Document1.
If I delete Circuit1, it will be deleted, but Document1 will not be deleted because Circuit2 exists.
If I then delete Circuit2, then Document1 will be deleted.

ex 3 ( , Circuit, , , , . , , .)
1 .
Circuit1 Document1.
1 Document1.
Circuit1, , Document1, 1 .

DB:
, 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();
}
+3
1

. delete-orphan , , . , , . 10.11 , . , delete-orphan :

  • - , .
  • , , , .

, :

    using (ISession session = sessionFactory.OpenSession())
    {
        foreach (var item in session.CreateCriteria<Model.Circuit>().List<Model.Circuit>())
        {
            item.Documents.Clear();
            session.Delete(item);
        }
        session.Flush();
        foreach (var item in session.CreateCriteria<Model.Issue>().List<Model.Issue>())
        {
            item.Documents.Clear();
            session.Delete(item);
        }
        session.Flush();
    }
0

Source: https://habr.com/ru/post/1781879/


All Articles