4

MVC 3では、DbContext.SaveChanges()を呼び出した後にデータベースをロールバックすることは可能ですか?

私のエンティティクラス:

public class BipEntities : DbContext
{
    public DbSet<Page> Pages { get; set; }
    public DbSet<ImageFile> ImageFiles { get; set; }
}

私がやろうとしているのは、ImageFileレコードをデータベースに挿入し、自動インクリメントされたIDを画像ファイル名として使用して、画像ファイルを別の場所に保存することです。System.IOに障害が発生した場合、データベースをロールバックしたいと思います。

BipEntities db = new BipEntities();
db.Database.Connection.Open();
DbTransaction tranx = db.Database.Connection.BeginTransaction();

ImageFile img = new ImageFile { CreatedAt = DateTime.Now };
db.ImageFiles.Add(img);
db.SaveChanges();

string filename = "img" + img.Id.ToString() + ".png";
try {
    //Works on system IO to process file
    tranx.Commit();

} Catch ( Exception) {
    tranx.Rollback();
}

db.Database.Connection.Close();

ただし、上記のコードでは、次のエラーメッセージが表示されます。

EntityConnection can only be constructed with a closed DbConnection.
4

2 に答える 2

2

を使用するか、トランザクション内で実行されるを使用して作成することによりDbContext、データベーストランザクションでラップする必要があります。TransactionScopeDbContextDbConnection

using (var con = new SqlConnection(conStr))
{
    con.Open();
    using (var tran = con.BeginTransaction())
    {
        var img = new Image();

        using (var db = new BipEntities(con))
        {
            db.Images.AddObject(img);

            db.SaveChanges();
        }

        // Write to disk here.
        WriteStuffToDisk(stuff, img.Id);

        tran.Commit();
    }        
}
于 2011-12-28T12:10:58.073 に答える
0

基本的に、.saveChanges() あなたのコミットです。ロールバックする場合は、を実行せず.saveChangesにデータベースアクセス層を閉じるだけで、変更は保存されません。

using(var db = new dbconnection())
{
    myEntity item = new myEntity { Name = "Hello" };

    db.tblofmyEntities.AddObject(item);

    if (item.Name != "FOO")
         db.SaveChanges();

}

名前が「FOO」ではないため、アイテムは保存されます。「FOO」の場合は保存されません。したがって、アプリケーションが到達すると}、アイテムは保存されません。ifブロックの前または内部で関数を呼び出すことができますが、.AddObject()大きな違いはありません。

于 2011-12-28T12:16:18.180 に答える