为什么我成功读取的Npgsql数据消失了?

时间:2011-10-26 13:31:27

标签: c# npgsql

我有以下代码形状。看来我误解了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!
    }
}

2 个答案:

答案 0 :(得分:2)

您没有详细说明连接的来源。假设它是这样的:

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

答案 1 :(得分:1)

NpgsqlCommand c = new NpgsqlCommand(...);
        NpgsqlDataReader dataread = c.ExecuteReader();

以上几行是DoQuery方法的本地化。因此,只要控件来自该方法,在此方法内部创建的每个对象都会失去其范围。因此,您丢失了数据,因为它是您在调用方法中引用的引用类型。

相关问题