从try / catch块返回产量

时间:2011-08-30 14:51:18

标签: c# transactions idisposable try-catch-finally yield-return

正如Eric Lippert在this article中所述,yield return条款中不允许try/catch

有一种很好的方法可以让我得到这样的东西,而不必手工编写我自己的IEnumerator

public IEnumerable<Data> GetData()
{
    var transaction = Session.BeginTransaction());
    try 
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
            yield return ProjectResult(result);  // <-- doesn't work

        session.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        throw;
    }
    finally
    {
        transaction.Dispose();
    }
}

2 个答案:

答案 0 :(得分:11)

我只是改变了这样的交易处理逻辑:

public IEnumerable<Data> GetData()
{
    var transaction = Session.BeginTransaction();
    bool rollback = true;
    try 
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
        {
            yield return ProjectResult(result);
        }

        rollback = false;
        session.Commit();
    }
    finally
    {
        if (rollback)
        {
            transaction.Rollback();
        }
        transaction.Dispose();
    }
}

或者,如果您的交易支持“dispose意味着回滚,除非它已提交”的想法:

public IEnumerable<Data> GetData()
{
    using (var transaction = Session.BeginTransaction();
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
        {
            yield return ProjectResult(result);
        }

        // Commits the tnrasaction, so disposing it won't roll it back.
        session.Commit();
    }
}

答案 1 :(得分:-1)

重新因子

foreach (var result in q.Enumerable()) 
  yield return ProjectResult(result);

进入一个单独的方法并简单地返回它的结果。