3

私は次のコード形状を持っています。C#メソッドの戻り値を誤解しているようです。「完全な」列挙子が空の列挙子として返される可能性はありますか?

class ThingDoer
{
    public NpgsqlDataReader DoQuery()
    {
        NpgsqlCommand c = new NpgsqlCommand(...);
        NpgsqlDataReader dataread = c.ExecuteReader();
        return dataread;  // Debugger confirms that six data are enumerable here.
    }
}

...

class OtherThing
{
    public void higherLevelFunction()
    {
        NpgsqlDataReader result = myThingDoer.DoQuery();
        result.Read();  // No data! result's enumerable returns nothing!
    }
}
4

2 に答える 2

3

接続がどこから来ているのか詳細はわかりません。それが次のようなものであると仮定します:

public NpgsqlDataReader DoQuery()
{
    using(NpgsqlConnection = GetConnectionCode())
    {
        NpgsqlCommand c = new NpgsqlCommand(...);
        NpgsqlDataReader dataread = c.ExecuteReader();
        return dataread;
    }//Connection closes at this using-scope being left because that triggers Dispose()
}

次に、次のように変更します。

public NpgsqlDataReader DoQuery()
{
    bool ownershipPassed = false;
    NpgsqlConnection conn = GetConnectionCode();
    try
    {
        NpgsqlCommand c = new NpgsqlCommand(...);
        NpgsqlDataReader dataread = c.ExecuteReader(CommandBehavior.CloseConnection);
        ownershipPassed = true;
        return dataread;
    }
    finally
    {
        if(!ownershipPassed)//only if we didn't create the reader than takes charge of the connection
          conn.Dispose();
    }
}

次に、リーダーを使用する場合は、リーダーを破棄して、データベースへの接続の基になる接続を破棄する必要があります。

public void higherLevelFunction()
{
    using(NpgsqlDataReader result = myThingDoer.DoQuery())
      result.Read();
}
于 2011-10-26T13:52:56.820 に答える
1
NpgsqlCommand c = new NpgsqlCommand(...);
        NpgsqlDataReader dataread = c.ExecuteReader();

上記の行は、メソッドDoQueryに対して非常にローカルです。したがって、コントロールがメソッドから出るとすぐに、このメソッド内に作成されたすべてのオブジェクトはそのスコープを失います。したがって、呼び出し元メソッドで参照している参照型であるため、データが失われます。

于 2011-10-26T13:36:44.180 に答える