我是nHibernate的新手,正设法了解从Web应用程序表单POST更新分离对象的正确方法。 (我们正在使用ASP.NET MVC)我尝试更新的对象包含(除其他事项外)一个子对象的IList,映射如下所示:<bag name="PlannedSlices" inverse="true" cascade="all-delete-orphan"> <key column="JobNumber" /> <one-to-many class="SliceClass" /></bag>我们已经安排了MVC编辑 View 表单,以便在将其回发时,我们的操作方法通过对象传递(包括子项的List 。我们通过该表单正确地往返所有实体ID。我们对post action方法的幼稚尝试会执行一个session.SaveOrUpdate(parentObject),它的parentObject已被默认的modelbinder从 View 窗体中删除。对于以下任何情况,这似乎都可以正常工作:创建一个新的父对象修改父级的属性添加新的子对象修改现有的子对象(查看nHibernate日志,我可以看到它正确地建立了对象是新对象还是现有对象,并发出了适当的UPDATE或INSERT)失败的情况是: -删除子对象-即,如果它们不在IList中,则不会从数据库中删除它们。没有异常(exception)或任何东西,只是不会被删除。我的理解是,这是因为nHibernate用于创建需要删除的子项列表的魔术不适用于分离的实例。我无法找到一个简单的示例,说明这种操作方法在nHibernate中应该是什么样(例如,将模型绑定(bind)器对象用作分离的nHibernate实例)-基于MS EF的示例(例如http://stephenwalther.com/blog/archive/2009/02/27/chapter-5-understanding-models.aspx)似乎使用了方法“ApplyPropertyChanges”将更改的属性从绑定(bind)到模型的对象复制到重新加载的实体实例。因此,毕竟,问题很简单-如果我让模型绑定(bind)器给我一个包含子对象集合的新对象,我该如何通过nHibernate更新该对象(其中“update”可能包括删除子对象)? (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 这是一个我想您正在尝试做的例子。如果我误解了您要做什么,请告诉我。给定以下“域”类:public class Person{ private IList<Pet> pets; protected Person() { } public Person(string name) { Name = name; pets = new List<Pet>(); } public virtual Guid Id { get; set; } public virtual string Name { get; set; } public virtual IEnumerable<Pet> Pets { get { return pets; } } public virtual void AddPet(Pet pet) { pets.Add(pet); } public virtual void RemovePet(Pet pet) { pets.Remove(pet); }}public class Pet{ protected Pet() { } public Pet(string name) { Name = name; } public virtual Guid Id { get; set; } public virtual string Name { get; set; }}使用以下映射: public class PersonMap : ClassMap<Person> { public PersonMap() { LazyLoad(); Id(x => x.Id).GeneratedBy.GuidComb(); Map(x => x.Name); HasMany(x => x.Pets) .Cascade.AllDeleteOrphan() .Access.AsLowerCaseField() .SetAttribute("lazy", "false"); } } public class PetMap : ClassMap<Pet> { public PetMap() { Id(x => x.Id).GeneratedBy.GuidComb(); Map(x => x.Name); } }此测试: [Test] public void CanDeleteChildren() { Person person = new Person("joe"); Pet dog = new Pet("dog"); Pet cat = new Pet("cat"); person.AddPet(dog); person.AddPet(cat); Repository.Save(person); UnitOfWork.Commit(); CreateSession(); UnitOfWork.BeginTransaction(); Person retrievedPerson = Repository.Get<Person>(person.Id); Repository.Evict(retrievedPerson); retrievedPerson.Name = "Evicted"; Assert.AreEqual(2, retrievedPerson.Pets.Count()); retrievedPerson.RemovePet(retrievedPerson.Pets.First()); Assert.AreEqual(1, retrievedPerson.Pets.Count()); Repository.Save(retrievedPerson); UnitOfWork.Commit(); CreateSession(); UnitOfWork.BeginTransaction(); retrievedPerson = Repository.Get<Person>(person.Id); Assert.AreEqual(1, retrievedPerson.Pets.Count()); }运行并生成以下sql:DeletingChildrenOfEvictedObject.CanDeleteChildren:已通过NHibernate:将INERT INTO [Person](名称,ID)值(@ p0,@ p1)插入; @ p0 ='joe',@ p1 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'NHibernate:插入[Pet](名称,ID)值(@ p0,@ p1); @ p0 ='狗',@ p1 ='464e59c7-74d0-4317-9c22-9bf801013abb'NHibernate:插入[Pet](名称,ID)值(@ p0,@ p1); @ p0 ='猫',@ p1 ='010c2fd9-59c4-4e66-94fb-9bf801013abb'NHibernate:更新[宠物]设置Person_id = @ p0,其中Id = @ p1; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2',@ p1 ='464e59c7-74d0-4317-9c22-9bf801013abb'NHibernate:更新[宠物]设置Person_id = @ p0,其中Id = @ p1; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2',@ p1 ='010c2fd9-59c4-4e66-94fb-9bf801013abb'NHibernate:SELECT person0_.Id作为Id5_0_,person0_.Name作为Name5_0_ FROM [Person] person0_ WHERE person0_.Id=@p0; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'NHibernate:选择pets0_.Person_id作为Person3_1_,pets0_.Id作为ID1_,pets0_.Id作为ID6_0_,pets0_.Name作为Name6_0_ FROM [Pet] pets0_ WHERE pets0_.Person_id=@p0; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'NHibernate:UPDATE [人员]设置名称= @ p0,其中ID = @ p1; @ p0 ='驱逐',@ p1 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'NHibernate:UPDATE [宠物]设置名称= @ p0,其中ID = @ p1; @ p0 ='狗',@ p1 ='464e59c7-74d0-4317-9c22-9bf801013abb'NHibernate:UPDATE [宠物] SET Person_id = null WHERE Person_id = @ p0 AND Id = @ p1; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2',@ p1 ='010c2fd9-59c4-4e66-94fb-9bf801013abb'NHibernate:从[宠物]的ID = @ p0处删除; @ p0 ='010c2fd9-59c4-4e66-94fb-9bf801013abb'NHibernate:SELECT person0_.Id作为Id5_0_,person0_.Name作为Name5_0_ FROM [Person] person0_ WHERE person0_.Id=@p0; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'NHibernate:选择pets0_.Person_id作为Person3_1_,pets0_.Id作为ID1_,pets0_.Id作为ID6_0_,pets0_.Name作为Name6_0_ FROM [Pet] pets0_ WHERE pets0_.Person_id=@p0; @ p0 ='cd123fc8-6163-42a5-aeeb-9bf801013ab2'注意从[宠物]中删除...因此,您需要做的是将修改后的集合手工休眠一个Person对象(在此示例中),它应该能够确定要删除的内容。确保已设置Cascade.AllDeleteOrphan()属性。关于asp.net-mvc - 从asp.net POST操作方法更新nhibernate实体的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/794314/ (adsbygoogle = window.adsbygoogle || []).push({});