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 に答える