出于集成测试的目的,我们提供数据并从SQL读取数据。为了避免测试数据库中的“垃圾”,它在事务中运行并回滚。
在运行此事务时,它会抛出'TransactionScope错误'异常:
using (var transaction = new TransactionScope())
{
// saving (submitchanges)
// reading (linq2sql select to get saved data) // 'Transaction has aborted' was thrown
// rollback
}
使用显式连接/事务处理时,它运行良好 - 但代码很难看。
我该怎么办?
环境:.NET 3.5 / C#,MSSQL2k8
详细例外:
System.Transactions.TransactionAbortedException:事务已中止。 ----> System.Transactions.TransactionPromotionException:尝试提升事务时失败。 ----> System.Data.SqlClient.SqlException:已经有一个与此命令关联的打开DataReader,必须先关闭它。*
答案 0 :(得分:1)
多年来我一直在努力解决这个问题。基本上有两个极端你必须选择:
注意我说“重置”,而不是“恢复”......它不一定非常密集。我提出了许多方法,包括分离和重新附加规范测试mdf文件(比恢复快得多,至少在那时),执行数据转储重置脚本(截断或删除所有表并重置它们) )。
最近,我一直在关注RedGate的Sql Compare ......我仍然不确定如何把它放在一起。但最终,我一直沿着事务/回滚路径走下去,并决定在测试方程中引入太多未经过单元测试的代码。
答案 1 :(得分:1)
如果您没有测试数据库结构,那么我建议将数据库从等式中删除,并采用依赖注入方法。如果您使用的是LINQ to SQL,而不是存储过程,这意味着您实际上可以控制感兴趣的数据来自何处,即在正常情况下它将是数据库,并且在测试中,它可以是预定义的对象集合。为了从数据中抽象使用,您必须使用一堆IQuariable<T>
属性定义数据提供程序接口/抽象类。默认实现将它们与数据库表链接,测试实现将在内存中生成它们。您现在要做的就是注入一个或另一个实现实例。