5

不知道我是否问正确的问题,请耐心等待我! NHibernate noob的位。流利NHibernate - HiLo计划的持久规范

我们正在使用流利的NH并具有以下ID生成方案的所有表

public class IdGenerationConvention : IIdConvention 
{ 
    public void Apply(IIdentityInstance instance) 
    { 
     var where = string.Format("TableKey = '{0}'", instance.EntityType.Name); 
     instance.GeneratedBy.HiLo("HiloPrimaryKeys", "NextHighValue", "1000", x => x.AddParam("where", where)); 
    } 
} 

我们有一个生成的HiloPrimaryKeys表,并与被部署期间运行数据的种子它的SQL脚本。这工作正常。

我现在正在尝试编写单元测试来验证我们的持久层,理想情况下在内存配置中使用SQLite来提高速度。这是我如何配置NH进行了检测:

[SetUp] 
public void SetupContext() 
{ 
    config = new SQLiteConfiguration() 
      .InMemory() 
      .ShowSql() 
      .Raw("hibernate.generate_statistics", "true"); 

    var nhConfig = Fluently.Configure() 
      .Database(PersistenceConfigurer) 
      .Mappings(mappings => 
       mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>() 
      .Conventions.AddFromAssemblyOf<IdGenerationConvention>()); 

    SessionSource = new SessionSource(nhConfig); 
    Session = SessionSource.CreateSession(); 
    SessionSource.BuildSchema(Session); 
} 

的问题是我不知道如何告诉NHibernate的有关我们的部署脚本,使其在测试过程中产生正确的架构和种子数据。

我得到的具体问题,运行以下PersistenceSpecification测试时:

[Test] 
public void ShouldAddDocumentToDatabaseWithSimpleValues() 
{ 
    new PersistenceSpecification<Document>(Session) 
      .CheckProperty(x => x.CreatedBy, "anonymous") 
      .CheckProperty(x => x.CreatedOn, new DateTime(1954, 12, 23)) 
      .CheckProperty(x => x.Reference, "anonymous") 
      .CheckProperty(x => x.IsMigrated, true) 
      .CheckReference(x => x.DocumentType, documentType) 
      .VerifyTheMappings(); 
} 

会抛出以下异常:

TestCase ... failed: 
Execute 
NHibernate.Exceptions.GenericADOException: 
     could not get or update next value[SQL: ] 
     ---> System.Data.SQLite.SQLiteException: SQLite error 
     no such column: TableKey 

所以我的推论是,它没有运行部署脚本当检查持久性规范时。

这种情况是否存在解决方案?我的谷歌似乎已经抛弃了这个。

回答

4

正如Brian所说,您可以在构建模式之后运行部署脚本。此代码的工作很适合我:

var config = new SQLiteConfiguration() 
     .InMemory() 
     .ShowSql() 
     .Raw("hibernate.generate_statistics", "true"); 

var nhConfig = Fluently.Configure() 
     .Database(config) 
     .Mappings(mappings => 
      mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>() 
     .Conventions.AddFromAssemblyOf<IdGenerationConvention>()); 

var SessionSource = new SessionSource(nhConfig); 
var Session = SessionSource.CreateSession(); 
SessionSource.BuildSchema(Session); 

// run the deployment script 
var deploymentScriptQuery = Session.CreateSQLQuery("ALTER TABLE HiloPrimaryKeys ADD COLUMN TableKey VARCHAR(255); INSERT INTO HiloPrimaryKeys (TableKey, NextHighValue) values ('Document', 1);"); 
deploymentScriptQuery.ExecuteUpdate(); 

部署脚本可以从文件等加载...

大厦FNH配置和数据库架构非常耗时的操作。如果使用该模式的测试计数增加,并且架构和配置由每个测试类构建,则执行测试套装将花费无法接受的时间量。应该在所有测试之间共享配置和模式。 Here是如何在不失去测试隔离的情况下实现的。

编辑: 如果测试中需要多个会话实例,则应打开连接池,或者应通过相同的连接创建两个会话。细节here ...

0

免责声明:我不是一个NHibernate的用户...

...但一个可能的解决办法是在测试的安装方法运行部署脚本(或者它的一些变化)(使用shell执行/ Process.Start),或者在运行这些测试之前在构建脚本中运行它。在这种情况下,如果每次测试都需要新的数据库,则可能需要添加清理。

+0

是的,我尝试过,但似乎'PersistenceSpecification'只能在NH生成的模式下工作,而不是你可能做出的任何改变(据我所知) – 2011-04-16 09:27:40

0

我们有一个SQL脚本,用于生成HiloPrimaryKeys表,并将它与在部署期间运行的数据一起播种。这工作正常。

您可以创建一个代表这个HiloPrimaryKeys表被映射的实体,并填写此表你的测试开始之前?你可以把它放在一个基类中,所有其他的测试都继承它,这样你就不必把它添加到每个测试类中。

这与Brian的解决方案类似,但是当您像自己的其他表一样进行自动映射时,将创建此表。