我有以下代码形状。看来我误解了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!
}
}
答案 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方法的本地化。因此,只要控件来自该方法,在此方法内部创建的每个对象都会失去其范围。因此,您丢失了数据,因为它是您在调用方法中引用的引用类型。