C#SqlDataReader被关闭

时间:2016-03-14 13:01:54

标签: c#

我不知道为什么会出现异常。它说在我尝试访问它之前,读者已经关闭了。为什么会这样?

以下是代码:

//Load Projects from SQL Server (nothing else)
public SPpowerPlantList loadProjectsFromServer(DateTime timestamp, string note, string sqlServer, string database)
{
    SqlConnection sqlConnection = new SqlConnection(String.Format(@"Integrated Security=SSPI;server={0};Initial Catalog={1};", sqlServer, database));
    sqlConnection.Open();

    string selectstring = "SELECT * FROM [dbo].[tblSPpowerPlant]"; //(WHERE note {0} = " + note + " AND timestamp {1} = " + timestamp;
        SqlCommand sqlSelectCommand = new SqlCommand(selectstring, sqlConnection);
    sqlSelectCommand.CommandType = CommandType.Text;
    sqlSelectCommand.CommandText = selectstring;

    SqlDataReader reader;

    SPpowerPlantList powerPlantList = new SPpowerPlantList();

    reader = sqlSelectCommand.ExecuteReader();

    //this line trowhs the exeption
    while (reader.Read())
    {
        foreach (SPpowerPlant powerPlant in powerPlantList)
        {
            powerPlant.ID = reader.GetInt32(0);
            powerPlant.projectName = reader.GetString(1).ToString();
            powerPlant.location = reader.GetString(2); 
            powerPlant.shortName = reader.GetString(3); 
            powerPlant.numberOfWtgs = reader.GetInt32(4); 
            powerPlant.mwWtg = reader.GetDouble(5); 
            powerPlant.mwTotal = reader.GetDouble(6); 
            powerPlant.projectShareWeb = reader.GetDouble(7); 
            powerPlant.mwWeb = reader.GetDouble(8); 
            powerPlant.phase = reader.GetString(9); 
            powerPlant.phaseNumber = reader.GetString(10);
            powerPlant.phaseDescription = reader.GetString(11); 
            powerPlant.projectProgress = reader.GetDouble(12); 
            powerPlant.mwDeveloped = reader.GetDouble(13); 
            powerPlant.projectManager = reader.GetString(14); 
            powerPlant.spaceUrl = reader.GetString(15); 
            powerPlant.country = reader.GetString(16); 
            powerPlant.technology = reader.GetString(17);
            powerPlant.state = reader.GetString(18);
            powerPlant.allPermits = reader.GetDateTime(19);
            powerPlant.cod = reader.GetDateTime(20);
            powerPlant.stateSince = reader.GetDateTime(21);
            powerPlant.spID = reader.GetInt32(22);
            powerPlant.currency = reader.GetString(23);
            powerPlant.possibleWtgTypes = reader.GetString(24);
            powerPlant.hubHeight = reader.GetString(25);
            powerPlant.visibility = reader.GetString(26);
            powerPlant.templateName = reader.GetString(27);

            powerPlantList.Add(powerPlant);
        }

        reader.Dispose();
        sqlConnection.Close(); 
    }

    return powerPlantList;
}

以下是例外(谷歌翻译):

  

由于数据阅读器已关闭,因此无法尝试读取访问权限。

我用谷歌尝试过但没有运气。所以任何帮助都会很棒。谢谢你的时间。

BTW抱歉,我的英语不是我母语,但我会继续学习。

2 个答案:

答案 0 :(得分:4)

代码行

reader.Dispose();
sqlConnection.Close(); 

位于while(reader.read())循环内。

此外,您最好使用using而不是自己调用Dispose()

public SPpowerPlantList loadProjectsFromServer(DateTime timestamp, string note, string sqlServer, string database)
{
    using(var sqlConnection = new SqlConnection(String.Format(@"Integrated Security=SSPI;server={0};Initial Catalog={1};", sqlServer, database)))
    {
        sqlConnection.Open();

        var selectstring = "SELECT * FROM [dbo].[tblSPpowerPlant]"; //(WHERE note {0} = " + note + " AND timestamp {1} = " + timestamp;
        var sqlSelectCommand = new SqlCommand(selectstring, sqlConnection);
        sqlSelectCommand.CommandType = CommandType.Text;
        sqlSelectCommand.CommandText = selectstring;

        SPpowerPlantList powerPlantList = new SPpowerPlantList();

        using(var reader = sqlSelectCommand.ExecuteReader())
        {
            while (reader.Read())
            {
                foreach (SPpowerPlant powerPlant in powerPlantList)
                {
                    powerPlant.ID = reader.GetInt32(0);
                    powerPlant.projectName = reader.GetString(1).ToString();
                    powerPlant.location = reader.GetString(2); 
                    powerPlant.shortName = reader.GetString(3); 
                    powerPlant.numberOfWtgs = reader.GetInt32(4); 
                    powerPlant.mwWtg = reader.GetDouble(5); 
                    powerPlant.mwTotal = reader.GetDouble(6); 
                    powerPlant.projectShareWeb = reader.GetDouble(7); 
                    powerPlant.mwWeb = reader.GetDouble(8); 
                    powerPlant.phase = reader.GetString(9); 
                    powerPlant.phaseNumber = reader.GetString(10);
                    powerPlant.phaseDescription = reader.GetString(11); 
                    powerPlant.projectProgress = reader.GetDouble(12); 
                    powerPlant.mwDeveloped = reader.GetDouble(13); 
                    powerPlant.projectManager = reader.GetString(14); 
                    powerPlant.spaceUrl = reader.GetString(15); 
                    powerPlant.country = reader.GetString(16); 
                    powerPlant.technology = reader.GetString(17);
                    powerPlant.state = reader.GetString(18);
                    powerPlant.allPermits = reader.GetDateTime(19);
                    powerPlant.cod = reader.GetDateTime(20);
                    powerPlant.stateSince = reader.GetDateTime(21);
                    powerPlant.spID = reader.GetInt32(22);
                    powerPlant.currency = reader.GetString(23);
                    powerPlant.possibleWtgTypes = reader.GetString(24);
                    powerPlant.hubHeight = reader.GetString(25);
                    powerPlant.visibility = reader.GetString(26);
                    powerPlant.templateName = reader.GetString(27);

                    powerPlantList.Add(powerPlant);
                }
            }
        }           

    }
    return powerPlantList;
}

答案 1 :(得分:1)

如果删除该foreach部分,则可以看到问题所在。

  1. 您检查阅读器是否已打开
  2. 你遍历动力装置列表,就像将每个powerPlant重新分配给读者中的同一记录一样
  3. 您关闭并丢弃阅读器
  4. 现在,检查它是否在while的顶部再次打开,这会引发异常
  5. 我相信你想从读者那里创建一个新的SPpowerPlant对象列表。您应该将代码更改为以下代码,然后释放阅读器。请注意,您应将所有Disposable对象包装在using语句中,如下面的阅读器所示。

    using(var reader = sqlSelectCommand.ExecuteReader()) // closes and disposes reader once it is out of scope
    {    
        while (reader.Read()) 
        {
            var powerPlant = new SPpowerPlant();
            powerPlant.templateName = reader.GetString(27);
            //// rest of calls to populate your item
            SPpowerPlantList.Add(powerPlant);
        }
    }