代码之家  ›  专栏  ›  技术社区  ›  Zebi

带有C#-Sqlite的NHibernate在.net2.0中没有DbConnection

  •  0
  • Zebi  · 技术社区  · 15 年前

    Nhibernate C# Sqlite .

    不幸的是,NHibernate要求一个连接是DbConnection,而C#-Sqlite驱动程序没有提供这个连接。我查看了源代码并注意到以下代码:

    #if NET_2_0
    public class SqliteConnection : DbConnection, ICloneable
    #else
        public class SqliteConnection : IDbConnection, ICloneable
    #endif
    

    更改代码是没有选择,因为这将等于写一个新的客户端,必须进行测试和维护。

    有没有人知道一个简单的解决方案来让c#sqlite的当前版本与NHibernate一起工作?

    3 回复  |  直到 13 年前
        1
  •  1
  •   Stefan Steinegger    15 年前

    我让NH创建连接,但将其存储在静态变量中,以便将其传递给后续会话。

    当我开始编写测试框架时,我有如下初始化代码:

    static IDbConnection staticSqliteConnection;
    
    if (staticSqlliteConnection == null)
    {
      sessionFactory.CreateSession().Connection;
    }
    

    然后我编写了一个ConnectionProvider类,如下所示:

    public class SingleConnectionProvider : DriverConnectionProvider
    {
        private static IDbConnection staticConnection = null;
    
        public static void ResetConnection()
        {
            if (staticConnection == null) return;
            staticConnection.Dispose();
            staticConnection = null;
        }
    
        public override IDbConnection GetConnection()
        {
            if (staticConnection == null) 
            {
                staticConnection = base.GetConnection();
            }
            if (staticConnection.State != ConnectionState.Open)
            {
                staticConnection.Open();
            }
            return staticConnection;
        }
    
        protected override void Dispose(bool isDisposing)
        {
            ResetConnection();
        }
    }
    

    在单元测试清理方法中,调用 SingleConnectionProvider.ResetConnection() 为下一次测试销毁数据库。

    整个过程当然不是完全线程安全的。您可以创建任意数量的会话,但应避免同时创建会话。

        2
  •  0
  •   Noah    15 年前

    #if NET_2_0
    public class SqliteConnection : DbConnection, ICloneable
    #else
        public class SqliteConnection : IDbConnection, ICloneable
    #endif
    

    您可以通过定义编译器选项看到这一点

        3
  •  0
  •   Zebi    15 年前

    我使用System.Data.SQLite和自定义连接提供程序解决了这个问题:

    public class SqLiteInMemoryConnectionProvider : DriverConnectionProvider
    {
        public static IDbConnection Connection;
    
        public static event EventHandler ConnectionReset;
    
        public static void ResetConnection()
        {
            if(Connection == null) return;
    
            Connection.Close();
            Connection.Open();
    
            if(ConnectionReset != null) ConnectionReset(null, new EventArgs());
        }
    
        public override IDbConnection GetConnection()
        {
            if (Connection == null)
            {
                Connection = base.GetConnection();
            }
            if (Connection.State != ConnectionState.Open)
            {
                Connection.Open();
            }
            return Connection;
        }
    
        public override void CloseConnection(IDbConnection conn) { }
    }
    

    与Stefan Steineggers解决方案的不同之处在于,我正在关闭并重新打开会话以重置,因为如果我只是处理了它,NHibernate无法获得新的连接。 此外,我还添加了一个事件,用于在我的工厂类中重建会话工厂(它将我们的模式导出到数据库)

    SqLiteInMemoryConnectionProvider.ConnectionReset += (s, _) => RebuildSessionFactory();