Search code examples
asp.netnhibernatenhibernate-mapping

Insert Row in a child table based on Foreign key using NHibernate


I'm hoping someone has run into this problem before and can help me out.In my Database I'm using tables relation between

Ex:Authors,Author Books,Booksstore(salesDetails)
**Authors table**
=================
Aid int (Identity and Primarykey),AuthorName varchar(50)
=================

***********
**Author Books table**
=================
BookID int(primary key),BookName nvarchar(50),Aid int (foreign key Authorstable(Aid))
=================

**************
**Booksstore table**
================
StoreID int(primary key),Totalsales int,BookID int (foreign key Author Bookstable(BookID))
================ 

I'm using Nhibernate and mapping above tables in the following
*********************
**Authorsdao.hdm.xml**
*********************
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Dal" namespace="Dal">
  <class name="AurthosDao,Dal" table="Aurthors Table" lazy="true">
    <id name="AId" column="AuthorID" type="int">
      <generator class="native" />
    </id>
    <property type="string" not-null="true" length="250" name="Authorname" column="AuthorName" />
    </class>
</hibernate-mapping>

*********************
**Authorbooksdao.hdm.xml**
*********************
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Dal" namespace="Dal">
  <class name="AurthorBooksDao,Dal" table="AuthorBookstable" lazy="true">
    <id name="AId" column="AuthorID">
      <generator class="foreign">
        <param name="property">AId</param>
      </generator>
    </id>
    <property type="int" not-null="true" name="BookId" column="BookID" />
    <property type="string" not-null="true" name="Bookname" column="BookName" />
    </class>
</hibernate-mapping>


*********************
**Booksstoredao.hdm.xml**
*********************
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Dal" namespace="Dal">
  <class name="BookStoreDao,Dal" table="Bookstoretable" lazy="true">
    <id name="BookId" column="BookID">
      <generator class="foreign">
        <param name="property">BookId</param>
      </generator>
    </id>
    <property type="int" not-null="true" name="StoreId" column="StoreID" />
    <property type="int" not-null="true" name="Totalsales" column="TotalSales" />
   </class>
</hibernate-mapping>

***************************
Now I have to insert the data from Asp.Net Nhibernate in to 3 tables in one transaction.



1)I'm inserting first in Authors table after that I'm trying to get that last inserting key from Authors table and pushing into Authorsbook table

2)After inserting into Autthorsbooks table trying to get last inserted BookID from AuthorsBook table and pushing into BookStore table.

If any help it would be appreciatable..

Radmin I'm using transcation in the following public IAuthors Aurthorsdata(PlanningManagerProxy proxy, String authorName,IBook books ,Ilist , IList attributes) { AuthorDao dao = new AuthorDao();

        using (ITransaction tx = proxy.MarcomManager.GetTransaction())
        {

            // Business logic of AuthorObjective


            dao.Name = authorName;

            tx.PersistenceManager.PlanningRepository.Save<AuthorDao>(dao);
            tx.Commit();

            AuthorDao  objList;
            using (ITransaction txGet = proxy.GetTransaction())
            {


                objList = txGet.PersistenceManager.PlanningRepository.Get<AuthorDao>(id);
                txGet.Commit();

            }
            var objId = from a in objList where a.AuthorID == authorId select a;

            using (ITransaction tx2 = proxy.MarcomManager.GetTransaction())
            {
                AuthorbooksDao objdao = new AuthorbooksDao();
                objdao.BookId = books.BookID;
                objdao.BookName=books.BookName;
                objdao.AuthorId= objId.AuthorId;
                tx2.PersistenceManager.PlanningRepository.Save<AuthorbooksDao>(objdao);
                tx2.Commit();

            }
            }
    }    

@Radim first I'm committing the transaction of Authors and then getting the last inserted record from AuthorDao(AuthorsTable) and then pushing into Bookstore table.But while mapping time the foreign key not allowing to insert?


Solution

  • Let's try this mapping (having your table declaration as a constant).

    C# classes:

      public class Author 
      {
         public virtual int ID { get; set; }
         public virtual string Authorname { get; set; }
      }
    
      public class Book
      {
         public virtual int ID { get; set; }
         public virtual Author Author { get; set; }
         public virtual string Bookname { get; set; }
      }
    
      public class BookStore
      {
         public virtual int ID { get; set; }
         public virtual Book Book { get; set; }
      }
    

    xml mapping:

    <class name="Author" table="Authors" lazy="true">
        <id name="ID" column="Aid" type="int">
          <generator class="native" />
        </id>
    
        <property type="string" not-null="true" length="250" name="Authorname" column="AuthorName" />
      </class>
    
      <class name="Book" table="AuthorBooks" lazy="true">
        <id name="ID" column="BookID">
          <generator class="native" />
        </id>
    
        <!-- reference Author -->
        <many-to-one name="Author" column="AID" cascade="all" />
    
        <property type="string" not-null="true" name="Bookname" column="BookName" />
        </class>
    
      <class name="BookStore" table="Bookstore" lazy="true">
        <id name="ID" column="StoreID">
          <generator class="native" />
        </id>
    
        <!-- reference Book -->
        <many-to-one name="Book" column="BookID" cascade="all" />
    
        <property type="int" not-null="true" name="Totalsales" column="TotalSales" />
      </class>
    

    and the code how to create author, book and store item - and persist them all:

      // instances creation
      var author = new Author { Authorname = "my author" };
      var book = new Book { Bookname = "my book "};
      var store = new BookStore { TotalSales = 1 };
    
      // references
      book.Author = author;
      store.Book = book;
    
      // cascade all will store them all with correct ID
      session.Save(author);
    

    NOTE: in your snippet are few incorrectnes, so the only way is to show an example on the green field. E.g. The file should be named ...hbm.xml (instead of ...hdm.xml, AurthosDao instead of AuthorsDao, etc.