不确定我是否在问正确的问题所以请耐心等待!一点NHibernate noob。
我们正在使用Fluent 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));
}
}
我们有一个SQL脚本可以生成HiloPrimaryKeys
表,并使用在部署期间运行的数据对其进行种子处理。这很好。
我现在正在尝试编写单元测试来验证我们的持久层,理想情况是在内存配置中使用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
所以我的推论是,它在检查持久性规范时没有运行部署脚本。
这种情况是否存在解决方案?我的Google-fu似乎让我对此感到遗憾。
答案 0 :(得分: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 ...
答案 1 :(得分:0)
免责声明:我不是NHibernate的用户......
...但是一种可能的解决方法是在测试的Setup方法中运行您的部署脚本(或其中的一些变体)(使用shell execute / Process.Start)或者在您之前的构建脚本中运行它运行这些测试。如果您希望每个测试都有一个新的数据库,则可能需要在这种情况下添加清理。
答案 2 :(得分:0)
我们有一个SQL脚本,可以生成HiloPrimaryKeys表,并使用在部署期间运行的数据为其播种。这工作正常。
您可以创建一个映射代表此HiloPrimaryKeys表的实体,并在测试开始之前填充此表吗?您可以将它放在所有其他测试继承的基类中,这样就不必将其添加到每个测试类中。
这与Brian的解决方案类似,但是当您像其他表一样进行自动化时,将创建此表。