SqlDataReader由于未知原因关闭

时间:2019-01-08 10:56:22

标签: c# asp.net

C#菜鸟在这里。我正在尝试使用下面的代码从SQL数据库中获取一些数据,但是出现错误:System.InvalidOperationException:'在关闭阅读器时,调用Read的尝试无效。'

在网上搜索答案后,我什么也没发现,也许有人可以看到哪里出了问题?

错误发生在:while(rdr.Read())

谢谢!

internal List<string> GetInflationByYearData(string Country, int StartYear, 
int EndYear)
        {
            string CS = 
ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
            using (SqlConnection con = new SqlConnection(CS))
            {
                SqlCommand cmd = new SqlCommand("SpCountryData", con)
                {
                    CommandType = System.Data.CommandType.StoredProcedure
                };
                cmd.Parameters.AddWithValue("@act", 
"getInflationByYearData");
                cmd.Parameters.AddWithValue("@Country", Country);
                cmd.Parameters.AddWithValue("@startYear", StartYear);
                cmd.Parameters.AddWithValue("@endYear", EndYear);
                var table = new DataTable();
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    {
                        table.Load(rdr);
                    };
                }
                //con.Close();
                List<string> labelList = new List<string>();
                List<string> valueList = new List<string>();
                if (table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        string label = row["Year"].ToString();
                        string value = row["Percentage"].ToString();
                        labelList.Add(label);
                        valueList.Add(value);
                    }
                }
                List<string> list = new List<string>();
                StringBuilder sbLabels = new StringBuilder();
                foreach (string lbl in labelList)
                {
                    sbLabels.Append(lbl + ",");
                }
                StringBuilder sbValues = new StringBuilder();
                foreach (string val in valueList)
                {
                    sbValues.Append(val + ",");
                }
                list.Add(sbLabels.ToString().Substring(0, sbLabels.Length - 
1));
                list.Add(sbValues.ToString().Substring(0, sbValues.Length - 
1));
                return list;
            }
        }

2 个答案:

答案 0 :(得分:5)

Load消耗了读者的心血;您应该任一具有一个while (rdr.Read())循环,或者调用table.Load(rdr),但不能同时使用两者。 Load基本上在内部执行相同的循环。

因此:删除循环-只需使用Load

但是!如果您想要的只是List<string>数据,则将其加载到DataTable似乎是不必要的步骤(DataTable not 轻量级的)-好像您可以在阅读器中完成 ,或者使用其他工具(例如“ dapper”)将其删除。

目前尚不清楚YearPercentage是什么数据类型,但是作为一个“精巧的”示例...

class MyRowThing {
    public int Year {get;set;}
    public decimal Percentage {get;set;}
}

var rawData = con.Query<MyRowThing>("SpCountryData",
    new { // params here
        act = "getInflationByYearData", Country,
       startYear = StartYear, endYear = EndYear
    }, commandType: CommandType.StoredProcedure).AsList();

// now loop over rawData, which is a List<MyRowThing> with the data

答案 1 :(得分:2)

替换:

  var table = new DataTable();
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    {
                        table.Load(rdr);
                    };
                }
                //con.Close();
                List<string> labelList = new List<string>();
                List<string> valueList = new List<string>();
                if (table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        string label = row["Year"].ToString();
                        string value = row["Percentage"].ToString();
                        labelList.Add(label);
                        valueList.Add(value);
                    }
                }

使用:

    con.Open();

    List<string> labelList = new List<string>();
    List<string> valueList = new List<string>();
    SqlDataReader rdr = cmd.ExecuteReader();
    while (rdr.Read())
    {
            labelList.Add(rdr["Year"].ToString());
            valueList.Add(rdr["Percentage"].ToString());
    }

将摆脱DataTable以获得更优化的代码。