简体   繁体   English

奇怪的NHibernate Sqllite.InMemory行为

[英]Odd NHibernate Sqllite.InMemory behaviour

I am trying to setup database unit tests using the Sqllite.InMemory functionality. 我正在尝试使用Sqllite.InMemory功能设置数据库单元测试。 If I run an unit test, everything is working fine. 如果我运行单元测试,则一切正常。 If I run the same test a second time I get an System.Data.SQLite.SQLiteException: no such table: Person 如果第二次运行相同的测试,则会得到System.Data.SQLite.SQLiteException:否这样的表:Person

After waiting for a while and/or (?) restarting Visual studio I can run the unit test once again. 等待片刻和/或(?)重新启动Visual Studio之后,我可以再次运行单元测试。

Is there something wrong with the configuration or the session handling? 配置或会话处理是否有问题?

public abstract class InMemoryDatabaseFixture : IDisposable
{
    private const string ConnectionString
        = "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1;";

    private readonly ISessionFactory _sessionFactory;
    private readonly ISession _session;

    protected InMemoryDatabaseFixture()
    {
        var config = SQLiteConfiguration.Standard.InMemory().ShowSql().ConnectionString(ConnectionString);
        _sessionFactory = Fluently.Configure()
            .Database(config)
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
            .BuildSessionFactory();

        _session = _sessionFactory.OpenSession();

        SessionContainer = MockRepository.GenerateMock<ISessionContainer>();
        SessionContainer.Stub(sc => sc.SessionFactory).Return(_sessionFactory);
        SessionContainer.Stub(sc => sc.Session).Return(_session);
    }

    protected ISessionContainer SessionContainer { get; private set; }

    public void Dispose()
    {
        _sessionFactory.Dispose();
        _session.Dispose();
    }
}

Here a simple usage of the base class: 这里是基类的简单用法:

[TestFixture]
public class FinderFixture : InMemoryDatabaseFixture
{
    [Test]
    public void Test()
    {
        var finder = new Finder(SessionContainer);

        var result = finder.Find();

        Assert.That(result, Is.Not.Null);
    }
}

Update : After some trials here is finally my working configuration. 更新 :经过一番尝试,这里终于是我的工作配置。 Exporting the schema after building the SessionFactory is doing the magic. 在构建SessionFactory之后导出架构确实很神奇。

Configuration configuration = null;
_sessionFactory = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
    .ExposeConfiguration(cfg => configuration = cfg)
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
    .BuildSessionFactory();

_session = _sessionFactory.OpenSession();
var export = new SchemaExport(configuration);
export.Execute(true, true, false, _session.Connection, null);

You have requested that connection pooling in the ADO.NET provider be enabled. 您已请求在ADO.NET提供程序中启用连接池。 This will keep the underlying connection active even after NHibernate has closed it. 即使NHibernate关闭了该连接,它也将使基础连接保持活动状态。

In my own unit tests, I have simply (based on your original code): 在我自己的单元测试中,我只是简单地(基于您的原始代码):

_sessionFactory = Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.InMemory())
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
        .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
        .BuildSessionFactory();

Also, since the session is generated from the session factory, it would be prudent to dispose all sessions before disposing the session factory. 另外,由于会话是从会话工厂生成的,因此在处置会话工厂之前,处置所有会话是明智的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM