Je suis nouveau à Castle Windsor/Fluent NHibernate/NHibernate et j'essaie de travailler avec chacun d'entre eux dans un projet .NET MVC3 comme un exercice d'apprentissage.FLuent NHibernate/Castle Windsor, Id = 0 en essayant de mettre à jour
suis passé par this excellent tutoriel pour y aller et essayer de stay away from repositories, a fini avec les classes/applications suivantes:
// 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<ContentPage> Pages { get; set; }
public Section()
{
Pages = new List<ContentPage>();
}
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<T> : ClassMap<T> where T : EntityBase
{
public EntityBaseMap()
{
Id(x => x.Id);
Map(x => x.Modified);
}
}
public class SectionMap : EntityBaseMap<Section>
{
public SectionMap()
{
Map(x => x.Name);
Map(x => x.Sortorder);
HasMany(x => x.Pages)
.Inverse()
.Cascade.All();
}
}
public class ContentPageMap : EntityBaseMap<ContentPage>
{
public ContentPageMap()
{
Map(x => x.Title);
Map(x => x.Sortorder);
Map(x => x.MetaKeywords);
Map(x => x.MetaDescription);
Map(x => x.Slug);
References(x => x.Section);
}
}
// SectionsController
private readonly ISession session;
public ActionResult Edit(int id)
{
Section section = session.QueryOver<Section>().Where(x => 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();
}
Le problème que je suis en cours d'exécution en est quand je modifier une « section », le formulaire s'affiche correctement et l'identifiant 'caché' a la valeur correcte. Cependant, lorsque ce formulaire est soumis, la valeur de la colonne id à l'intérieur de l'action 'Edit' est 0. Ce qui est intéressant, c'est que 'Modified' fait également partie de la classe EntityBase, mais cela est bien rempli. Inutile de dire que l'ajout d'une nouvelle 'Section' n'est pas un problème car l'ID est généré correctement par la base de données. Donc, je sais que j'ai définitivement manqué quelque chose quelque part, et je ne le vois tout simplement pas. Quelqu'un peut-il faire la lumière sur ce qui me manque?
Edit: Merci à @ la réponse de Linkgoron ci-dessous, a ajouté une ViewModel ...
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<Section>(id);
if (section == null)
{
return HttpNotFound();
}
return View(section);
}
[HttpPost]
public ActionResult Edit(SectionViewModel sectionInputModel)
{
var section = session.Get<Section>(sectionInputModel.Id);
section.Modified = DateTime.Now;
if (ModelState.IsValid)
{
Mapper.CreateMap<SectionViewModel, Section>();
Mapper.Map(sectionInputModel, section);
session.SaveOrUpdate(section);
return RedirectToAction("Index");
}
return View();
}
Maintenant, je reçois le code correct, et il est mis en correspondance sur correctement aussi, mais saveOrUpdate qui ne fonctionne pas semblent modifier les données dans la base de données. Quoi d'autre ai-je manqué?
Édition 2: Doh!
nécessaires pour Purger à savoir
session.SaveOrUpdate(section);
session.Flush();
return RedirectToAction("Index");
Merci.
Vous ne devez pas utiliser Mapper.CreateMap() à chaque fois, il suffit d'exécuter CreateMap une fois, dans l'application_start.C'est une opération lourde qui utilise la réflexion. En outre, lorsque vous utilisez nhibernate, vous devez toujours exécuter des opérations dans une transaction http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions –
Linkgoron
Yep - figuré autant. Ce qui précède était juste pour que ça marche. Merci beaucoup pour les pointeurs! – seekay