How-To: Using the N* Stack, part 5
我们一直都在关注 NHibernate 和持久化。在本篇中我们会纠正之前模式和映射的问题来通过我们的测试。本篇结束之后我们会减少对 NHibernate 的关注。下一部分开始集中于整合 Ninject 我们的控制反转/依赖注入的框架并加入到 ASP.NET MVC 中。讲点其他有意思的事根据 Fabio Maulo 介绍NHibernate 的LOGO可能是一只睡着的土拨鼠。明确你要纠正什么当你修正BUG的时候你应该只修改BUG。很显然我们编写测试我们可以找出哪里有问题不明显的是要知道哪些“错误”其实不是错误。自白有时我会先编码然后测试。有时我会先穿裤子再穿衬衫。其实只要你离开家之前衣服都穿好了顺序不是那么重要。同样编码和测试的顺序也不是那么重要。下面是 part 4中 NUnit 的测试结果2个通过3个失败5个抛出异常。对我来说10个测试中有2个通过了已经非常好了。下面让我们一一解决剩余的问题。最低限度的 NHibernate 调试NHibernate 使用 log4net 作为日志框架它可以快速准确的显示出 NUnit 和其他测试工具的日志。将 log4net.dll 添加到测试项目的引用中添加 app.config 文件添加一个新类 BaseFixture设置你所有的 test fixture 继承 BaseFixture下面是 app.config 文件中 log4net 的配置?xml version1.0 encodingutf-8 ? configuration configSections section namelog4net typelog4net.Config.Log4NetConfigurationSectionHandler,log4net/ /configSections log4net appender nameDebugger typelog4net.Appender.ConsoleAppender layout typelog4net.Layout.PatternLayout conversionPattern value%date [%thread] %-5level %logger - %message%newline/ /layout /appender logger nameNHibernate.SQL level valueALL/ appender-ref refDebugger/ /logger /log4net /configurationBaseFixture 的代码public abstract class BaseFixture { protected static readonly log4net.ILog Log GetLogger(); private static log4net.ILog GetLogger() { log4net.Config.XmlConfigurator.Configure(); return log4net.LogManager.GetLogger(typeof(BaseFixture)); } }我们只需要调用一次 log4net.Config.XmlConfiguration.Configure()它将从 app.config 中加载日志的配置通过 ConsoleAppender log4net会记录下 Console.Out 输出的任何信息。使用示例的配置我们可以看到执行的 NHibernate SQL。如果你需要更强大的东西可以参阅 Ayende 的 NHProf.问题#1NStackExample.Data.Tests.CourseMappingTests.CanCascadeOrphanDeleteFromCourseToSections: NHibernate.TransientObjectException : object references an unsaved transient instance -save the transient instance before flushing. Type: NStackExample.Section, Entity: NStackExample.SectionCourse Course new Course { Subject SUBJ, CourseNumber 1234, Title Title, Description Description, Hours 3 }; Section Section new Section { FacultyName FacultyName, RoomNumber R1, SectionNumber 1, Term Term }; Course.AddSection(Section); using (ITransaction Tran Session.BeginTransaction()) { ID (Guid) Session.Save(Course);