Note that there are some explanatory texts on larger screens.

plurals
  1. POFLuent NHibernate/Castle Windsor, Id = 0 when trying to Update
    text
    copied!<p>I'm new to Castle Windsor/Fluent NHibernate / NHibernate and am trying to work with all of them in a .NET MVC3 project as a learning exercise. </p> <p>Went through <a href="http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx" rel="nofollow">this</a> excellent tutorial to get going, and trying to <a href="http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx" rel="nofollow">stay away from repositories</a>, ended up with the following classes/mappings:</p> <pre><code> // Entities public abstract class EntityBase { public virtual int Id { get; private set; } public virtual DateTime Modified { get; set; } } public class Section : EntityBase { public virtual String Name { get; set; } public virtual int Sortorder { get; set; } public virtual IList&lt;ContentPage&gt; Pages { get; set; } public Section() { Pages = new List&lt;ContentPage&gt;(); } public virtual void AddContentPage(ContentPage contentPage) { contentPage.Section = this; this.Pages.Add(contentPage); } } public class ContentPage : EntityBase { public virtual String Title { get; set; } public virtual int Sortorder { get; set; } public virtual String MetaKeywords { get; set; } public virtual String MetaDescription { get; set; } public virtual String Slug { get; set; } public virtual Section Section { get; set; } } //Mappings public abstract class EntityBaseMap&lt;T&gt; : ClassMap&lt;T&gt; where T : EntityBase { public EntityBaseMap() { Id(x =&gt; x.Id); Map(x =&gt; x.Modified); } } public class SectionMap : EntityBaseMap&lt;Section&gt; { public SectionMap() { Map(x =&gt; x.Name); Map(x =&gt; x.Sortorder); HasMany(x =&gt; x.Pages) .Inverse() .Cascade.All(); } } public class ContentPageMap : EntityBaseMap&lt;ContentPage&gt; { public ContentPageMap() { Map(x =&gt; x.Title); Map(x =&gt; x.Sortorder); Map(x =&gt; x.MetaKeywords); Map(x =&gt; x.MetaDescription); Map(x =&gt; x.Slug); References(x =&gt; x.Section); } } // SectionsController private readonly ISession session; public ActionResult Edit(int id) { Section section = session.QueryOver&lt;Section&gt;().Where(x =&gt; x.Id == id).SingleOrDefault(); if (section == null) { return HttpNotFound(); } return View(section); } [HttpPost] public ActionResult Edit(Section section) { section.Modified = DateTime.Now; if (ModelState.IsValid) { session.Update(section); return RedirectToAction("Index"); } return View(); } </code></pre> <p>The problem I'm running into is when I edit a 'Section', the form displays fine and the hidden 'id' has the correct value. However, when that form is submitted, the value of the id column inside the 'Edit' action is 0. What's interesting is the 'Modified' is also part of the EntityBase class, but that's populated fine.</p> <p>Needless to say, adding a new 'Section' is not a problem as the id is generated correctly by the database.</p> <p>So I know I definitely missed something somewhere, and I'm just not seeing it. Can anyone please shed any light on what I'm missing?</p> <p><strong>Edit: Thanks to @Linkgoron's answer below, added a ViewModel...</strong></p> <pre><code>public class SectionViewModel { public int Id { get; set; } [Required(ErrorMessage = "Section Name is required")] [StringLength(25, ErrorMessage = "Name must be less than 25 characters")] public String Name { get; set; } [Required] public int Sortorder { get; set; } } // Updated Controller methods public ActionResult Edit(int id) { Section section = session.Load&lt;Section&gt;(id); if (section == null) { return HttpNotFound(); } return View(section); } [HttpPost] public ActionResult Edit(SectionViewModel sectionInputModel) { var section = session.Get&lt;Section&gt;(sectionInputModel.Id); section.Modified = DateTime.Now; if (ModelState.IsValid) { Mapper.CreateMap&lt;SectionViewModel, Section&gt;(); Mapper.Map(sectionInputModel, section); session.SaveOrUpdate(section); return RedirectToAction("Index"); } return View(); } </code></pre> <p>Now I do get the correct id, and it is mapped over correctly as well, but SaveOrUpdate doesn't seem to modify the data in the database. What else did I miss?</p> <p><strong>Edit 2: Doh!</strong></p> <p>Needed to Flush i.e.</p> <pre><code>session.SaveOrUpdate(section); session.Flush(); return RedirectToAction("Index"); </code></pre> <p>Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload