与SqlDataAdapter的结果不一致.Fill和SqlDataReader.Read

本文关键字:SqlDataReader Read Fill 不一致 SqlDataAdapter 结果 | 更新日期: 2023-09-27 17:53:54

我有一个SQL数据库的各种表,我想读到DataTable对象。为此,我使用了SqlDataAdapter。Fill,除了一张表之外,它对所有表都很有效,叫做"问题"。在这个表上,该方法运行时不会抛出任何异常,但是最终得到的DataTable只有3321行,而SQL表有9800行。"问题"表的代码与其他表的代码相同:

adapter.SelectCommand = new SqlCommand("SELECT * FROM [Problems]", my_connection);
adapter.Fill(my_dataset, "Problems");

我监听适配器。FillError和适配器。更新错误状态,但没有捕获任何错误。因此,我决定使用SqlDataReader(下面的代码)顺序读取表。这工作得很好,并捕获了完整的9,800行。这使我担心使用SqlDataAdapter。Fill可能会丢失其他表的数据,因此我对为SqlDataReader编写的方法进行了一般化,使我能够按顺序读取任何表(下面还有代码)。但是当我尝试使用这种一般化的方法时,我又只得到了3321行!

我想能够读取我的SQL数据库到数据表,而不用担心我丢失数据。

"问题"的顺序读取代码(这是实际工作的代码):

    public static DataTable GetAllProblems()
    {
        DataTable table = new DataTable("Problems");
        table.Columns.Add(new DataColumn("ExerciseID", typeof(int)));
        table.Columns.Add(new DataColumn("ParentID", typeof(int)));
        table.Columns.Add(new DataColumn("AnswerFields", typeof(string)));
        table.PrimaryKey = new DataColumn[] { table.Columns[0] };
        DataRow dr;
        SqlCommand com = new SqlCommand("SELECT * FROM [Problems]", ProblemDBPortConnection());
        if (com == null) throw new Exception("WTF");
        string a;
        int ex_id, parent_id;
        com.Connection.Open();
        SqlDataReader rdr = com.ExecuteReader();
        while(rdr.Read())
        {
            dr = table.NewRow();
            a = rdr["Answers"].ToString();
            ex_id = (int)rdr["ExerciseID"];
            parent_id = -1;
            if (!DBNull.Value.Equals(rdr["ParentID"])) parent_id = (int)rdr["ParentID"];
            dr["ExerciseID"] = ex_id;
            dr["ParentID"] = parent_id;
            dr["AnswerFields"] = ProblemAnswerFields(a);
            table.Rows.Add(dr);
        }
        rdr.Close();
        com.Connection.Close();
        return table;
    }

接下来是上述方法的泛化,它在"问题"表上似乎以与SqlDataAdapter相同的鬼鬼祟祟的方式失败。填充方法。在我的代码中,我通过

调用方法
my_dataset.Tables.Add(GetTable("Problems", "SELECT * FROM [Problems]", new Tuple<string, Type>("ExerciseID", typeof(int)), new Tuple<string, Type>("ParentID", typeof(int)), new Tuple<string, Type>("AnswerFields", typeof(string))));

方法本身是

    public static DataTable GetTable(string tableName, string selectCommand, params Tuple<string, Type>[] fields)
    {
        SqlCommand com = new SqlCommand(selectCommand, ProblemDBConnection());
        if(com==null)
            throw new Exception("WTF");
        if(fields.Length == 0)
            throw new Exception("WTF");
        DataTable table = new DataTable(tableName);
        DataColumn dc;
        for(int i=0; i<fields.Length; i++)
        {
            if(fields[i].Item2 == typeof(string))
                dc = new DataColumn(fields[i].Item1, typeof(string));
            else
            {
                if(fields[i].Item2 != typeof(int))
                    throw new Exception("WTF");
                dc = new DataColumn(fields[i].Item1, typeof(int));
            }
            table.Columns.Add(dc);
        }
        table.PrimaryKey = new DataColumn[] {table.Columns[0]};
        com.Connection.Open();
        SqlDataReader rdr = com.ExecuteReader();
        DataRow dr;
        while (rdr.Read())
        {
            dr = table.NewRow();
            for (int i = 0; i < fields.Length; i++)
            {
                if (fields[i].Item1 == "AnswerFields")
                {
                    if (DBNull.Value.Equals(rdr["Answers"]))
                        dr[fields[i].Item1] = "";
                    else 
                        dr[fields[i].Item1] = ProblemAnswerFields(rdr["Answers"].ToString());
                }
                else if (DBNull.Value.Equals(rdr[fields[i].Item1]))
                {
                    if (fields[i].Item2 == typeof(string))
                        dr[fields[i].Item1] = "";
                    else
                    {
                        dr[fields[i].Item1] = -1;
                    }
                }
                else
                {
                    if (fields[i].Item2 == typeof(string))
                        dr[fields[i].Item1] = rdr[fields[i].Item1].ToString();
                    else
                    {
                        dr[fields[i].Item1] = (int)rdr[fields[i].Item1];
                    }
                }
            }
            table.Rows.Add(dr);
        }
        rdr.Close();
        com.Connection.Close();
        return table;
    }

与SqlDataAdapter的结果不一致.Fill和SqlDataReader.Read

没关系,在失败的情况下,我意外地使用了一个旧的连接,它从一个已弃用的数据库版本中提取了所有数据。> & lt;看来我不是很聪明。