I have two simple classes that reference each other as a one-to-many relationship, defined below:
public class Project { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IList<Document> Documents { get; set; } } public class Document { public virtual int Id { get; set; } public string FileName { get; set; } }
And my mappings are defined as:
public class ProjectMapping : ClassMap<Project> { public ProjectMapping() { Table("Projects"); Id(x => x.Id).Column("Project_Id").GeneratedBy.TriggerIdentity(); HasMany(x => x.Documents) .Table("Documents") .KeyColumn("Document_Project_Id") .Cascade.AllDeleteOrphan() .Not.KeyNullable(); Map(x => x.Name).Column("Project_Name"); } } public class DocumentMapping : ClassMap<Document> { public DocumentMapping() { Table("Documents"); Id(x => x.Id).Column("Document_Id").GeneratedBy.TriggerIdentity(); Map(x => x.FileName).Column("Document_File_Name"); } }
Everything seems to be working fine, adding / updating documents and calling session.Save (project) reflects the correct changes in my database, however, if I want to remove a document from the list of documents associated with the project and the .Save (project) remote call session the document is never deleted from the database.
Any ideas why everything else will work except deletion?
EDIT: My MVC 4 project is configured using Fluent NHibernate as follows:
public class SessionFactoryHelper { public static ISessionFactory CreateSessionFactory() { var c = Fluently.Configure(); try {
My repository is defined as follows:
public class Repository<T> : IRepository<T> { public virtual ISession Session { get { return MvcApplication.SessionFactory.GetCurrentSession(); } } public T FindById(int iId) { return Session.Get<T>(iId); } public void Save(T obj) { using (var transaction = Session.BeginTransaction()) { try { Session.Save(obj); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); Log.WriteLine(ex.ToString()); } } } public T SaveOrUpdate(T obj) { using (var transaction = Session.BeginTransaction()) { try { Session.SaveOrUpdate(obj); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); Log.WriteLine(ex.ToString()); } } return obj; } public T Update(T obj) { using (var transaction = Session.BeginTransaction()) { try { Session.Update(obj); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); Log.WriteLine(ex.ToString()); } } return obj; } }
I have 2 actions defined in my ProjectController, as follows:
private IRepository<Project> repository; public ProjectsController() { repository = new Repository<Project>(); } public ActionResult Edit(int iId) { Project project = repository.FindById(iId); if (project == null) return HttpNotFound(); return View(project); } [HttpPost] public ActionResult Edit(Project project) { project = repository.Update(project); return View(project); }
If I have to delete a document in my first action (without HttpPost):
project.Documents.RemoveAt(0); repository.Update(project);
The correct row is deleted from the database. However, if I have to do the same in action with the HttpPost attribute, the string is never deleted.
It should also be noted that if I add a document to the project. Documents in action with the HttpPost attribute, repository.Update (project) successfully adds a row with the correct foreign key reference for the project. This only happens when a document is deleted.