我正在使用npoco,尝试使用事务,我无法使用AbortTransaction
方法回滚数据库中的任何内容。
public class ItemRepository
{
private Func<Database> _db;
public ItemRepository(Func<Database> db)
{
_db = db;
}
Public void Update(){
using (_db().Transaction)
{
_db().BeginTransaction();
foreach (var item in itemToUpdate.Items)
{
_db().Insert(item);
if (SomethingIsNotCorrect())
{
_db().AbortTransaction();
}
}
_db().CompleteTransaction();
}
}}
从测试类调用:
_db = () => new Database(String.Format("DataSource={0};Persist Security Info=False;", DbPath),"System.Data.SqlServerCe.4.0");
_itemRepository = new ItemRepository(() => _db());
_itemRepository.Update();
-------------建议回答后编辑:
var db = _db();
using (db.Transaction)
{
db.BeginTransaction();
foreach (var item in itemToUpdate.Items)
{
db.Insert(item);
db.Transaction.Commit();
if (GetNutrientConns(itemToUpdate).Count > 2)
{
db.AbortTransaction();
}
}
db.CompleteTransaction();
}
现在我必须使用db.Transaction.Commit()在db中插入一些内容。然后在尝试运行db.AbortTransaction()时收到错误消息:
“此SqlCeTransaction已完成;它已不再可用。”
答案 0 :(得分:2)
从您的更新中,很清楚问题是什么。您正在创建一个工厂函数,该函数实例化并返回一个新的连接/ datacontext,并将其传递到您的存储库构造函数中。到目前为止一切都很好。
然后,您将继续调用从工厂函数获得的新的Database
实例上的每个与事务相关的调用,这没有任何意义。在构造函数中,使用工厂函数实际获取Database
实例,并将 存储在字段中。根据需要多次使用。
public class ItemRepository
{
private Database _db;
public ItemRepository(Func<Database> dbFactory)
{
_db = dbFactory();
}
...
}
更新:正如Mike C所指出的,为了进一步限制datacontext的范围和生命周期,最好存储工厂并创建一个Database
实例,该实例位于Update
方法,如下:
public class ItemRepository
{
private Func<Database> _dbFactory;
public ItemRepository(Func<Database> dbFactory)
{
_dbFactory = dbFactory;
}
public void Update() {
var db = _dbFactory();
// Now use db wherever you were using _db()
...
}
}
答案 1 :(得分:0)
最终解决方案更新方法:
var db = _dbFactory();
public void Update() {
try
{
db.BeginTransaction();
foreach(item in itemlist)
{
db.Insert(item);
}
db.CompleteTransaction();
}
catch(Exception)
{
db.Transaction.Rollback();
}
我不确定异常是否需要Rollback,因为当我使用抛出异常进行测试时,事务会消失。