如何避免重写相同的使用语句?

时间:2015-09-11 13:27:45

标签: c# entity-framework nested using idisposable

有没有办法在Disposable对象中创建嵌套使用,所以这段代码:

using (var ctx = new MyEntities())
{
    ctx.Connection.Open();
    using (var tx = dbContext.Connection.BeginTransaction())
    {
        // ... do awesome things here

        ctx.SaveChanges();
        tx.Commit();
    }
}

这样的事情:

using (var txContext = new TransactionContext())
{
    // ... do awesome things here
}

目前我有:

public class TransactionContext : IDisposable
{
    private MyEntities DbContext { get; set; }
    private DbTransaction Transaction { get; set; }

    public TransactionContext()
    {
        DbContext = new MyEntities();
        DbContext.Connection.Open();

        Transaction = DbContext.Connection.BeginTransaction();
    }

    void IDisposable.Dispose()
    {
        try
        {
            DbContext.SaveChanges();
            Transaction.Commit();
        }
        catch (Exception exception)
        {
            Transaction.Rollback();
            DbContext.Dispose();
        }
    }
}

我不确定处理不同Disposables的方式是否正确,尤其是在出现错误/异常的情况下。

1 个答案:

答案 0 :(得分:2)

使用方法代替类可能更好。

private static void RunInTransaction(Action<MyEntities, DbTransaction> action)
{
    using (var ctx = new MyEntities())
    {
        ctx.Connection.Open();
        using (var tx = ctx.Connection.BeginTransaction())
        {
            action(ctx, tx);
            ctx.SaveChanges();
            tx.Commit();
        }
    }
}

然后你就可以这样称呼它。

RunInTransaction((ctx,tx) => 
{
    // ... do awesome things here
}); 

您还可以创建一个返回值

的版本
private static T RunInTransactionAndReturn<T>(
    Func<MyEntities, DbTransaction, T> function)
{
    using (var ctx = new MyEntities())
    {
        ctx.Connection.Open();
        using (var tx = ctx.Connection.BeginTransaction())
        {
            var result = function(ctx, tx);
            ctx.SaveChanges();
            tx.Commit();
            return result;
        }
    }
}

然后你就可以这样称呼它。

var result = RunInTransactionAndReturn((ctx,tx) => 
{
    // ... do awesome things here
    return someResult;
});