0

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 は完了しました。使用できなくなりました。」

4

2 に答える 2

2

あなたの更新から、問題が何であるかはかなり明確です。新しい接続/データ コンテキストをインスタンス化して返すファクトリ関数を作成し、それをリポジトリ コンストラクタに渡します。ここまでは順調ですね。

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()
        ...
    }
}
于 2014-10-29T13:31:44.993 に答える
0

最終的なソリューションの更新方法:

var db = _dbFactory();
public void Update() {
try
{
    db.BeginTransaction();
    foreach(item in itemlist)
    {
        db.Insert(item);
    }
    db.CompleteTransaction();
}
catch(Exception)
{
    db.Transaction.Rollback();
}

例外をスローしてテストするとトランザクションが消えるため、例外でロールバックが必要かどうかはわかりません。

于 2014-10-30T10:28:51.277 に答える