【问题标题】:Can't add new row to a datatable [c#]无法将新行添加到数据表 [c#]
【发布时间】:2016-12-28 07:43:14
【问题描述】:

我有一个数据集,它存储在 XML 文件中。当应用程序启动并且 XML 文件尚不存在时,我想向我的数据集添加一些行并将其保存在 XML 中。我使用以下代码来做到这一点:

        partiesDb = new Parties();

        //...
        DataTable partyDsTable = partiesDb.Tables["party"]; //partiesDb is DataSet object
        for (int i = 0; i < size; i++)
        {
            DataRow row = partyDsTable.NewRow(); // HERE THE CODE STOPS
            row["sth"] = sth;
            row["sth"] = "0";
            row["id"] = "1";
            if (!partyDsTable.Rows.Contains(row))
            {
                partyDsTable.Rows.Add(row);
            }
        }
        System.Windows.Forms.MessageBox.Show(partyDsTable.Rows[0]["sth"].ToString());
        partiesDb.WriteXml(path);

然后什么也没有发生。甚至消息框也不显示。该功能在创建新行时停止,我不知道为什么。你能帮帮我吗?

[编辑]: 此代码工作正常:

            partiesDb = new Parties();
            DataTable dsTable = partiesDb.Tables["party"];
            DataRow dsRow = dsTable.NewRow();
            dsRow["name"] = "";
            dsRow["id"] = "";
            dsRow["votes"] = "";
            dsTable.Rows.Add(dsRow);
            partiesDb.WriteXml(partiesDbPath);

我不知道为什么会这样,但是当我添加循环时它不会...

【问题讨论】:

  • 该代码在哪里?如果 XML 尚不存在,该表是否存在?是否为空?
  • 是的,程序启动时表为空,并在设计器中定义。代码位于函数中,在表单构造函数中调用。
  • @g2556 你不能向空变量添加东西。
  • 把代码放在一个按钮点击开发,你会看到错误-NRE
  • @g2556 您确实需要将异常消息和内部异常(如果有)添加到您的问题中。我怀疑应用程序只是“停止”。

标签: c# xml datatable dataset datarow


【解决方案1】:

您不能向空变量添加内容。因此,如果 partyDsTable 为 null,则需要对其进行实例化。

DataTable partyDsTable = partiesDb.Tables["party"]; //partiesDb is DataSet object

if(partyDsTable == null) // instantiate it
    partyDsTable = new DataTable();

for (int i = 0; i < size; i++)
{
    ....

【讨论】:

  • 我刚刚编辑了这个问题。我不确定数据表是否为空,因为我在尝试添加行之前已经实例化了数据集
  • @g2556 您确实需要将异常消息和内部异常(如果有)添加到您的问题中。我怀疑应用程序只是“停止”。
  • 没有任何例外。应用程序根本没有停止,我仍然可以在表单上使用控件。
  • @g2556 那么这里到底有什么问题呢? “代码在这里停止”是什么意思?
【解决方案2】:
DataTable partyDsTable = partiesDb.Tables["party"]; //partiesDb is DataSet object
    for (int i = 0; i < size; i++)// "size" does not look like it's set to anything. If "size" is 0, then the loop will not loop. 
    {

            partyDsTable.Rows.Add(new object[] {sth,"0","1"});//you should probably make the columns into the correct type if you are using integers.

    }
    System.Windows.Forms.MessageBox.Show(partyDsTable.Rows[0]["sth"].ToString());
    partiesDb.WriteXml(path);

【讨论】:

  • Size 不是 0。我没有使用整数。
  • @g2556 那么如果size 不是整数,为什么还要将它与整数进行比较?
  • 我的意思是行中的属性类型不是整数。
  • Size 显然是一个整数 (INT I=0;i
  • 最有可能的是,您希望“size”成为您正在输入的数组的长度,或者您正在输入的列表的计数。你还没有向我们展示你的方法的开始,所以我不能告诉你那可能是什么,但除非你将 size 设置为某种东西,否则你的循环将无法工作。
【解决方案3】:

此外,如果您创建一个字段与数据库表中的项目匹配的类,您可以使用反射做各种事情,以使您的数据始终保持良好状态:

public static DataTable create_DataTable_From_Generic_Class(Type t)
    {
        DataTable d = new DataTable();
        FieldInfo[] fI = t.GetFields();
        for(int i = 0; i < fI.Length; i++)
        {
            DataColumn dC = new DataColumn(fI[i].Name, fI[i].FieldType);
            d.Columns.Add(dC);
        }
        return d;
    }
    public static object[] Create_Datatable_Row_From_Generic_Class(Type t, object instance,DataTable dt)
    {

        FieldInfo[] f = t.GetFields();
        object[] ret = new object[f.Length];
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            ret[i] = t.GetField(dt.Columns[i].ColumnName).GetValue(instance);

        }
        return ret;

    }
    public static List<string[]> getParams(Type type, bool convertToSQL)
    {


        List<string[]> ret = new List<string[]>();
        Dictionary<string, object> properties = new Dictionary<string, object>();
        foreach (FieldInfo prop in type.GetFields())
            properties.Add(prop.Name, prop.FieldType);
        foreach (string key in properties.Keys)
        {
            string[] r = { key, properties[key].ToString().Replace("System.", "") };
            ret.Add(r);
        }
        if (convertToSQL)
        {
            return convertFromNetToSQLDataTypes(ret);

        }
        else
        {
            return ret;
        }
    }
    private static List<string[]> convertFromNetToSQLDataTypes(List<string[]> list)
    {
        foreach (string[] data in list)
        {
            data[1] = data[1].Replace("Int16", "tinyint");
            data[1] = data[1].Replace("Int32", "int");
            data[1] = data[1].Replace("Int64", "bigint");
            data[1] = data[1].Replace("Double", "float");
            data[1] = data[1].Replace("Boolean", "tinyint");
            data[1] = data[1].Replace("Double", "float");
            data[1] = data[1].Replace("Long", "bigint");
            data[1] = data[1].Replace("String", "varchar(100)");
        }
        return list;
    }
    public static object[] sql_Reader_To_Type(Type t, SqlDataReader r)
    {
        List<object> ret = new List<object>();
        while (r.Read())
        {
            FieldInfo[] f = t.GetFields();
            object o = Activator.CreateInstance(t);
            for (int i = 0; i < f.Length; i++)
            {
                string thisType = f[i].FieldType.ToString();
                switch (thisType)
                {
                    case "System.String":

                        f[i].SetValue(o, Convert.ToString(r[f[i].Name]));
                        break;
                    case "System.Int16":
                        f[i].SetValue(o, Convert.ToInt16(r[f[i].Name]));
                        break;
                    case "System.Int32":
                        f[i].SetValue(o, Convert.ToInt32(r[f[i].Name]));
                        break;
                    case "System.Int64":
                        f[i].SetValue(o, Convert.ToInt64(r[f[i].Name]));
                        break;
                    case "System.Double":
                       // Console.WriteLine("converting " + f[i].Name + " to double");
                        double th;
                        if (r[f[i].Name] == null)
                        {
                            th = 0;
                        }
                        else
                        {
                            if (r[f[i].Name].GetType() == typeof(DBNull))
                            {
                                th = 0;
                            }
                            else
                            {
                                th = Convert.ToDouble(r[f[i].Name]);
                            }
                        }
                        try { f[i].SetValue(o, th); }
                        catch (Exception e1)
                        {
                            throw new Exception("can't convert " + f[i].Name + " to doube - value =" + th);
                        }
                        break;
                    case "System.Boolean":
                        f[i].SetValue(o, Convert.ToInt32(r[f[i].Name]) == 1 ? true : false);
                        break;
                    case "System.DateTime":
                        f[i].SetValue(o, Convert.ToDateTime(r[f[i].Name]));
                        break;
                    default:
                        throw new Exception("Missed data type in sql select in getClassMembers class line 73");

                }
            }
            ret.Add(o);

        }
        return ret.ToArray();


    }

一直如此。您可以像这样使用反射来创建与您的类匹配的表,自动创建插入或过程调用,并且永远不会使用不正确的数据类型或再次使字段乱序。

【讨论】:

  • 我不明白这段代码...请查看我的问题中的编辑。
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 2015-09-30
相关资源
最近更新 更多