在应用程序中, 当你对子对象进行了一些改变你肯定不希望需要自己去想着还需要对父对象进行哪些操作这样是非常繁琐的。好在 NHibernate 提供了级联的功能你不需要做这些事了。如果你的映射是正确的你就只需要保存子对象其他的工作你都不需要理会。对于一些人尤其像我这样的这是一个很大的工作量这就是为什么我们要测试映射。[Test()] public void CanCascadeSaveFromCourseToSections() { using (SQLiteDatabaseScopeCourseMapping Scope new SQLiteDatabaseScopeCourseMapping()) { using (ISession Session Scope.OpenSession()) { Guid ID; Term Term new Term { Name Fall 2009, StartDate new System.DateTime(2009, 9, 1), EndDate new System.DateTime(2009, 12, 1) }; //Were not testing the cascade of section - term here using (ITransaction Tran Session.BeginTransaction()) { Session.Save(Term); Tran.Commit(); } Session.Clear(); Course Course new Course { Subject SUBJ, CourseNumber 1234, Title Title, Description Description, Hours 3 }; Section Section1 new Section { FacultyName FacultyName, RoomNumber R1, SectionNumber 1, Term Term }; Section Section2 new Section { FacultyName FacultyName, RoomNumber R1, SectionNumber 2, Term Term }; Course.AddSection(Section1); Course.AddSection(Section2); //Test saving using (ITransaction Tran Session.BeginTransaction()) { ID (Guid) Session.Save(Course); Tran.Commit(); } Session.Clear(); //Check the results using (ITransaction Tran Session.BeginTransaction()) { Course Session.GetCourse(ID); Assert.AreEqual(2, Course.Sections.Count); Assert.AreEqual(1, Course.Sections .Where(S S.Equals(Section1)).Count(), Course.Sections does not contain section 1.); Assert.AreEqual(1, Course.Sections .Where(S S.Equals(Section2)).Count(), Course.Sections does not contain section 2.); Tran.Commit(); } } } }上面的测试将确保档你保存 course 的时候也同样会保存对 section 的操作。下面看看它是如何工作的获取一个新的 SQLite 数据库虽然我们不会测试 term 但是因为 section 的需要所以我们也需要在数据库中建立创建一个 course 和两个 section保存 course清空 session获取到 course确保它有两个 section当你从 course 中移除一个 section 将会发生什么呢当然任何一个 section 都需要有一个父对象也就是 course 。请记住我们在映射里指定的是非空的。更重要的是现实世界中不会有独立的 section 。所以当 section 成为孤儿的时候它将被删除掉下面我们来进行这样的一个测试[Test()] public void CanCascadeOrphanDeleteFromCourseToSections() { using (SQLiteDatabaseScopeCourseMapping Scope new SQLiteDatabaseScopeCourseMapping()) { using (ISession Session Scope.OpenSession()) { Guid ID; Term Term new Term { Name Fall 2009, StartDate new System.DateTime(2009, 9, 1), EndDate new System.DateTime(2009, 12, 1) }; using (ITransaction Tran Session.BeginTransaction()) { //Were not testing the cascade of section - term here Session.Save(Term); Tran.Commit(); } Session.Clear(); Course Course new Course { Subject SUBJ, CourseNumber 1234, Title Title, Description Description, Hours 3 }; Section Section1 new Section { FacultyName FacultyName, RoomNumber R1, SectionNumber 1, Term Term }; Section Section2 new Section { FacultyName FacultyName, RoomNumber R1, SectionNumber 2, Term Term }; Course.AddSection(Section1); Course.AddSection(Section2); using (ITransaction Tran Session.BeginTransaction()) { Session.Save(Course); Tran.Commit(); } Session.Clear(); //Test removing Course.RemoveSection(Section1); using (ITransaction Tran Session.BeginTransaction()) { ID (Guid) Session.Save(Course); Tran.Commit(); } Session.Clear(); //Check the results using (ITransaction Tran Session.BeginTransaction()) { Course Session.GetCourse(ID); Assert.AreEqual(1, Course.Sections.Count()); Assert.AreEqual(0, Course.Sections .Where(S S.Equals(Section1)).Count(), Course.Sections still contains section 1); Tran.Commit(); } } } }我希望大家能和我是一样的心态除了查询测试当我们写 DAO 层的时候就要对 NHibernate 进行测试。我们对其他的实体类也都要进行相同类型的测试。但是…那么你肯定在想“这么做太混乱了肯定无法编译就算可以差不多所有的测试都会失败”是的如果