7

正如 Eric Lippert 在本文中所描述的,在子句中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();
    }
}
4

2 回答 2

12

我只是像这样更改事务处理逻辑:

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();
    }
}

或者,如果您的事务支持“除非已提交,否则处置意味着回滚”的想法:

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();
    }
}
于 2011-08-30T14:54:41.383 回答
-2

重构

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

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

于 2011-08-30T14:55:57.153 回答