使用 SQLite“没有这样的表”测试 NHibernate - 生成模式

Posted

技术标签:

【中文标题】使用 SQLite“没有这样的表”测试 NHibernate - 生成模式【英文标题】:Testing NHibernate with SQLite "No Such Table" - schema is generated 【发布时间】:2011-05-18 13:39:48 【问题描述】:

我正在尝试使用内存中的 SQLite 数据库来测试 NHibernate 提供的数据层。

我已经阅读了大量关于如何设置此设置的博客和文章,但我现在很困惑为什么它不起作用。

问题 - 当我运行单元测试时,我收到错误“没有这样的表:学生”。我读过的文章表明这​​是因为没有生成架构,或者我的 SchemaExport 和查询之间的连接正在关闭。我已经检查了我能想到的所有地方,但看不到这两种情况是如何发生的。

我的测试输出日志如下所示:

OPEN CONNECTION

drop table if exists "Student"

drop table if exists "Tutor"

create table "Student" (
    ID  integer,
   Name TEXT,
   DoB DATETIME,
   TutorId INTEGER,
   primary key (ID)
)

create table "Tutor" (
    ID  integer,
   Name TEXT,
   primary key (ID)
)
NHibernate: INSERT INTO "Student" (Name, DoB, TutorId) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 'Text1', @p1 = 01/12/2010 14:55:05, @p2 = NULL
14:55:05,750 ERROR [TestRunnerThread] AbstractBatcher [(null)]- Could not execute query: INSERT INTO "Student" (Name, DoB, TutorId) VALUES (@p0, @p1, @p2); select last_insert_rowid()
System.Data.SQLite.SQLiteException (0x80004005): SQLite error

no such table: Student

at System.Data.SQLite.SQLite3.Prepare(String strSql, SQLiteStatement previous, String& strRemain)

at System.Data.SQLite.SQLiteCommand.BuildNextCommand()

at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index)

at System.Data.SQLite.SQLiteDataReader.NextResult()

at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)

at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)

at System.Data.SQLite.SQLiteCommand.ExecuteDbDataReader(CommandBehavior behavior)

at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()

at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)

14:55:05,781 ERROR [TestRunnerThread] ADOExceptionReporter [(null)]- SQLite error
no such table: Student
DISPOSE
CLOSING CONNECTION

最初我使用我自己的代码进行连接/会话管理,但已经转移到 this blog post 中的代码转换为 C#,并对 DBConfig 方法和一些调试语句进行了一些更改以显示连接状态。

private FluentNHibernate.Cfg.Db.IPersistenceConfigurer GetDBConfig()

    return SQLiteConfiguration.Standard
                               .ConnectionString((ConnectionStringBuilder cs) => cs.Is(CONNECTION_STRING))
                               .ProxyFactoryFactory("NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu")
                               .Raw("connection.release_mode", "on_close");

我在阅读this后添加了on_close

我的测试代码如下所示:

[Test]
public void CanGetStudentById()

    using (var scope = new SQLiteDatabaseScope<StudentMapping>())
    
        using (ISession sess = scope.OpenSession())
        
            // Arrange
            var repo = new StudentRepository();
            repo.Save(new Student()  Name = "Text1", DoB = DateTime.Now );

            // Act
            var student = repo.GetById(1);

            // Assert
            Assert.IsNotNull(student);
            Assert.AreEqual("Text1", student.Name);
        
   

我在这里忽略了什么?

更新:我创建了一个连接到 SQLite 文件数据库的类的副本,它运行良好。所以它必须与关闭连接有关。

【问题讨论】:

【参考方案1】:

如果你把你的测试方法改成下面这样,行得通吗?

[Test]
public void CanGetStudentById()

    using (var scope = new SQLiteDatabaseScope<StudentMapping>())
    
        using (ISession sess = scope.OpenSession())
        
            // Arrange
            sess.Save(new Student()  Name = "Text1", DoB = DateTime.Now );

            // Act
            var student = sess.Get<Student>(1);

            // Assert
            Assert.IsNotNull(student);
            Assert.AreEqual("Text1", student.Name);
        
   

我会冒险猜测您的 StudentRepository 正在打开自己的会话,因此看不到表。

【讨论】:

当然!太感谢了!这正是问题所在。不知道我将如何解决它,但至少我知道我现在在做什么 :) 它也回答了为什么我的测试也相互冲突! 查看上下文会话 (nhforge.org/doc/nh/en/index.html#architecture-current-session),特别是 CurrentSessionContext 和 ISessionFactory.GetCurrentSession()。

以上是关于使用 SQLite“没有这样的表”测试 NHibernate - 生成模式的主要内容,如果未能解决你的问题,请参考以下文章

Scala Slick 内存数据库 SQLite 没有这样的表

FATAL EXCEPTION:后台任务android.database.sqlite.SQLiteException:没有这样的表。

使用内存 sql lite 对流利的 nhibernate 存储库进行单元测试 - 没有这样的表错误

如何解决android.database.sqlite.SQLiteException:没有这样的表错误?

Django / sqlite3“OperationalError:没有这样的表”关于线程操作

SQLAlchemy:没有这样的表,即使它们是实际创建的