NHibernate 与 C#-Sqlite 在 > .NET 2.0 中没有 DbConnection
Posted
技术标签:
【中文标题】NHibernate 与 C#-Sqlite 在 > .NET 2.0 中没有 DbConnection【英文标题】:NHibernate with C#-Sqlite has no DbConnection in > .NET 2.0 【发布时间】:2010-08-12 11:30:41 【问题描述】:我尝试使用 C# Sqlite 运行我的单元测试,而不是使用此博客文章作为指导,而不是使用真正的数据库或模拟我们的数据库层:Nhibernate C# Sqlite。
不幸的是,NHibernate 要求连接是 C#-Sqlite 驱动程序未提供的 DbConnection。我查看了源代码并注意到以下代码:
#if NET_2_0
public class SqliteConnection : DbConnection, ICloneable
#else
public class SqliteConnection : IDbConnection, ICloneable
#endif
显然,作者决定停止使用“旧”基类并改用 IDbConnection、IDbTransaction 等接口。
更改代码是没有选择的,因为这等于编写一个必须测试和维护的新客户端。
有谁知道让当前版本的 c#sqlite 与 NHibernate 一起工作的简单解决方案?
【问题讨论】:
我不确定问题到底出在哪里。我可以告诉你我是如何使用 sqlite 进行测试的...... 异常是:15:03:28,877 错误 [7] SchemaValidator [(null)]- 无法获取数据库元数据 System.InvalidCastException: Das Objekt des Typs "Community.CsharpSqlite.SQLiteClient.SqliteConnection" kann nicht 在 Typ “System.Data.Common.DbConnection” umgewandelt werden。北NHibernate.Tool.hbm2ddl.ManagedProviderConnectionHelper.Prepare() 北NHibernate.Tool.hbm2ddl.SchemaValidator.Validate() 我是移植 C#SQLite 的人。我没有意识到任何人仍然需要 NET 2.0 支持,因为所有论坛 cmets 都鼓励放弃它。此外,在大多数情况下,客户端是由 Mono 项目组提供的。如果您确实需要 Net 2.0 定义编译器选项 NET_2_0,如果这不起作用,请在 groups.google.com/group/csharp-sqlite 上开始讨论或在此处请求 csharpsqlite.uservoice.com/forums/41270-general 您尝试过连接提供商吗?成功了吗? 至少它一开始并没有让我崩溃。明天我会尝试使用会话工厂并报告;) 【参考方案1】:我正在使用 sqlite 进行测试。我有不同的方法。
我让 NH 创建连接,但将其存储在静态变量中以将其传递给后续会话。
当我开始写测试框架的时候,我有这样的初始化代码:
static IDbConnection staticSqliteConnection;
if (staticSqlliteConnection == null)
sessionFactory.CreateSession().Connection;
然后我遇到了一些问题,并且我的生产代码中有太多的测试特定代码(我宁愿没有)。如果您将连接传递给会话,Hi-Lo id 生成器也不起作用。
然后我写了一个 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()
会破坏数据库以进行下一次测试。
整个事情当然不是完全线程安全的。您可以根据需要创建任意数量的会话,但应避免同时创建它们。
【讨论】:
感谢您的解决方案,我将尝试自己实现连接提供程序来解决问题。目前我只是一个测试创建一个新的会话工厂来测试 Sqlite 是如何工作的。 “Fluently.Configure()....BuildSessionFactory()” 抛出上述错误消息。从长远来看,我想用基于 sqlite 数据库的真实工厂替换所有模拟会话工厂。【参考方案2】:如果您查看您的代码示例,
#if NET_2_0
public class SqliteConnection : DbConnection, ICloneable
#else
public class SqliteConnection : IDbConnection, ICloneable
#endif
您可以看到,通过定义编译器选项NET_2_0,并重新编译,它将暴露旧接口
【讨论】:
啊 - 我认为 NET_2_0 是一个“内置”选项,如“调试”,并试图构建面向 .net 2.0 的项目,但没有成功。我会在星期一试试这个。感谢您移植 SQLite! 无法使用 NET_2_0 进行编译 :( DbConnectionFactory 现在被标记为“内部” - 代码无法编译。即使我将目标框架更改为 2.0。我会尽快尝试 Stefan Steineggers 的回答我手头有一些时间。【参考方案3】:我使用 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();
【讨论】:
以上是关于NHibernate 与 C#-Sqlite 在 > .NET 2.0 中没有 DbConnection的主要内容,如果未能解决你的问题,请参考以下文章
在SQLite上使用NHibernate时获取“Dababase被锁定”(没有事务的多进程)
Fluent NHibernate and Mysql,SQLite
NHibernate、SQLite 和 Cyrillic 字符:区分大小写和回退查询
使用 SQLite“没有这样的表”测试 NHibernate - 生成模式