在使用NHib的架构生成工具后,验证您的SQLite数据库是否真的在那里的最简单最有效的方法是什么?
干杯,
Berryl
修改
我希望有一些与ISession相关的东西(比如连接属性)可以测试;有时当运行一系列测试时,它看起来像是一个很好的会话(IsOpen和IsConnected都是真的),但是数据库不存在(对它的查询得到的错误就像'没有这样的表')。
编辑 - 我现在在做什么
连接字符串&其他cfg属性
public static Configuration GetSQLiteConfig()
{
return new Configuration()
.SetProperty(ENV.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionString, "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1")
.SetProperty(ENV.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(ENV.ReleaseConnections, "on_close")
.SetProperty(ENV.CurrentSessionContextClass, typeof (ThreadStaticSessionContext).AssemblyQualifiedName);
}
我现在如何测试db,因为缺少“更好”的东西(这会测试映射)
public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
{
Check.RequireNotNull<ISessionFactory>(sessionFactory);
Check.Require(session.IsOpen && session.IsConnected);
_verifyMappings(sessionFactory, session);
}
private static void _verifyMappings(ISessionFactory sessionFactory, ISession session) {
try {
foreach (var entry in sessionFactory.GetAllClassMetadata())
{
session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
.SetMaxResults(0).List();
}
}
catch (Exception ex) {
Console.WriteLine(ex);
throw;
}
}
public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
{
Check.Require(!sessionFactory.IsClosed);
Check.Require(session.IsOpen && session.IsConnected);
try {
foreach (var entry in sessionFactory.GetAllClassMetadata())
{
session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
.SetMaxResults(0).List();
}
}
catch (Exception ex) {
Debug.WriteLine(ex);
throw;
}
}
每当打开一个新会话时,我都会在会话提供程序中生成模式:
public ISession Session
{
get
{
var session = (ISession)CallContext.GetData(_lookupSessionKey);
try
{
if (session == null)
{
_log.Debug("Opening new Session for this context.");
session = FactoryContext.Factory.OpenSession();
if(RunTypeBehaviorQualifier != RunType.Production)
SchemaManager.GenerateNewDb(FactoryContext.Cfg, session.Connection);
CallContext.SetData(_lookupSessionKey, session);
}
}
catch (HibernateException ex)
{
throw new InfrastructureException(ex);
}
return session;
}
}
现在这可能过度设计,但我需要多个数据库连接,而且我一直无法保持简单和安全。工作。这也是一个问题的很多信息,但也许其他人实际上已经把这一切都归结为一门科学。下面的测试在它自己的测试夹具中运行良好,但不能与其他测试结合使用。
[Test]
public void Schema_CanGenerateNewDbWithSchemaApplied()
{
DbMappingTestHelpers.VerifyAllMappings(_dbContext.FactoryContext.Factory, _dbContext.Session);
}
答案 0 :(得分:1)
Berryl,
据我所知,你正在使用不同的连接来对抗映射的实体。有没有要求您使用多个“真实”数据库连接的义务?我的意思是,您的测试可以共享相同的会话(逻辑上)吗?如果没有,您只需将数据库配置为:
<property name="connection.connection_string">Data Source=NonTransactionalDB.txt;Version=3;New=True;Pooling=True;Max Pool Size=1;</property>
它的重要部分是汇集选项。由于每个会话都将使用相同的连接,因此每次重新创建模式都不会有问题。
但是,重要的是要记住,它会向您介绍有关交易的一些限制。 As SQLite can't handle more than one transaction per connection,并行运行测试可能会给您带来问题(例如“数据库文件被锁定”异常“)。干杯,
菲利普
答案 1 :(得分:0)
Berryl,只是为了让它更容易想象,我会发布另一个答案。如果对你有帮助,请随意给我另一个。 :)
以下是我用来检查我的NH配置对象是否配置正确的代码。
// assert: verify some properties just to see if connection properties were applyed ane entities mapped
Assert.AreEqual<string>(cfg.Properties["connection.connection_string"], @"Server=localhost;Initial Catalog=MoveFrameworkDataNHibernate;User Id=sa;Password=sa");
Assert.AreEqual<string>(cfg.Properties["dialect"], "NHibernate.Dialect.MsSql2000Dialect");
Assert.IsNotNull(cfg.GetClassMapping(typeof(MappedEntity)));
真诚地,我也不安全,因为DB可以检查配置对象,但这是一种了解方式:是的,我的实体在那里,我指向正确的数据库。
我知道你害怕使用第二个SQLite连接并且数据库在前一个连接中暴露,所以你会得到不需要的异常,但据我所知,唯一的其他选项是检查你的实体是否是会有类似下面的代码。但是,当它引用SessionFactory时,它只能帮助上一个选项。
tx.Session.SessionFactory.GetClassMetadata(typeof(MappedEntity)) != null
在这种情况下,我能想到的最后一个选项是使用EXISTS检查直接执行SQL到您的数据库。我不知道所有数据库实现之间的EXISTS命令是多么不可知,但是像我们在这里谈论的简单检查一样,这应该不是一个大问题。
希望这有帮助!
顺便说一句:这是jfneis。 Neis是姓氏。与薯条,炸薯条等无关。 :)干杯。
菲利普