0

I have a child , parent relationship in my application e.g.One Post can have many Comments(One to Many relationship). Ive completed the code for mapping, I need to write a code so when I insert a child into DB it inserts the parent ID too. At the moment my code doesnt insert the parent id only inserts other details of child.Can someone help me unpdating my code please?

Models:

namespace MvcApplication7.Models
{
    public class Post
    {
        public virtual int Id { get; set; }
        [Display(Name = "Post")] 
        public virtual string PostText { get; set; }
        public virtual IList<Comment> Comments { get; set; }
    }
}

namespace MvcApplication7.Models
{
    public class Comment
    {
        public virtual int Id { get; set; }
        public virtual Post Post { get; set; }

        [Display(Name = "Comments")] 
        public virtual string CommentText { get; set; }
    }
}

NHibenate mappings:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="MvcApplication7" namespace="MvcApplication7.Models">

      <class name="Post" table="Posts" dynamic-update="true" >
        <cache usage="read-write"/>
        <id name="Id" column="Id" type="int">
          <generator class="sequence">
            <param name="sequence">posts_id_seq</param>
          </generator>
        </id>
        <property name="PostText" column="Post"/>
        <bag name="Comments" inverse="true" lazy="true" >
          <key column="PostId"/>
          <one-to-many class="Comment"/>
        </bag>
      </class>

      <class name="Comment" table="Comments" dynamic-update="true" >
        <cache usage="read-write"/>
        <id name="Id" column="CommentId" type="int">
          <generator class="sequence">
            <param name="sequence">comments_commentid_seq</param>
          </generator>
        </id>
        <property name="CommentText" column="Comment"/>
        <many-to-one name="Post" class="Post" column="PostId" />
      </class>

    </hibernate-mapping>

Database tables:

CREATE TABLE comments
(
  commentid serial NOT NULL,
  postid integer,
  comment text,
  CONSTRAINT commentid PRIMARY KEY (commentid),
  CONSTRAINT postid FOREIGN KEY (postid)
      REFERENCES posts (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE comments
  OWNER TO postgres;
*********************************************************
CREATE TABLE posts
(
  id serial NOT NULL,
  post text,
  CONSTRAINT id PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE posts
  OWNER TO postgres;

The code that needs updating is the MVC controller which is as follows:

  public ActionResult Create()
  {
      return View();
  }


  [HttpPost]
  public ActionResult Create(Comment comments)
  {
      try
      {
          using (ISession session = NHIbernateSession.OpenSession())
          {
              using (ITransaction transaction = session.BeginTransaction())
              {
                  session.Save(comments);
                  transaction.Commit();  
              }
          }

          return RedirectToAction("Index");
      }
      catch (Exception exception)
      {
          return View();
      }
  }
5
  • Are you setting the Post property of the Comment to the Post and adding the Comment to the Post's Comment collection? That's all that you should have to do. Commented Sep 16, 2014 at 12:07
  • Thats exactly what Ive done but when I insert a new comment the foreign key is empty thats why I thought maybe Im missing something in the controller where I insert a new record in DB. @tom.dietrich Commented Sep 16, 2014 at 12:18
  • Could you post the code where you are performing that association? Commented Sep 16, 2014 at 12:19
  • Ive done this in properties. I have posted all my code. what else do I need? @tom.dietrich Commented Sep 16, 2014 at 12:22
  • I'll post it as an answer so we can have formatting. Commented Sep 16, 2014 at 12:27

2 Answers 2

2

I don't see the code where you associate your new Comments to your Post.

// Somehow get the target Post and store it the post variable, then
post.Comments.Add(comments)
comments.Post = post;

Session.Save(comments);
Session.Save(post);
Session.Commit();
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer. what do you mean by : "Somehow get the target Post and store it the post variable, then". Also where do I need to write the code you posted? @tom.dietrich
Ideally you should have a repository where you are doing your interactions with NHibernate, but you seem to have settled on the approach of doing this in your Controller action, so this code would go in your controller action. As for getting the target post, I don't have enough of your code base to be able to tell how that should work. If you have the ID for the post passed into your controller action, you could fetch it in a NHibernate query.
Can you explain how I can do it with repository please? @tom.dietrich
Do a quick Google for Repository Pattern. But I'll warn you it's a bit of a rabbit hole, there are lots of OOD concepts that you'll need to grok to get it.
I sorted my problem by doing what you said: I pass the ID in the view like this: @Html.ActionLink("Add Comments", "Create", "Comments", new { id = item.Id }, item.Id) and get that id in my create action in controller like this: var postObj = session.Get<Post>(id); comments.Post = postObj; using (ITransaction transaction = session.BeginTransaction()) { session.Save(comments); transaction.Commit(); } @tom.dietrich
|
0

Change your Post class like this

public class Post
{
    public virtual int Id { get; set; }
    [Display(Name = "Post")] 
    public virtual string PostText { get; set; }
    public virtual IList<Comment> Comments { get; protected set; }

    public Post()
    {
         Comments = new List<Comment>();
    }

    public virtual void AddComment(Comment comment)
    {
        if (!Comments.Contains(comment))
        {
             Comments.Add(comment);
             comment.Post = this;
        }
    }
}

And in your controller get the post using the session and add the Comment to it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.