重复的输出目标 - OleDB

时间:2017-09-26 19:15:56

标签: c#

我有一个插入查询,我试图在foreach循环下执行以插入多个值。但是,当我添加多个文本框行时,出现错误System.Data.OleDb.OleDbException: Duplicate output destination at 'childName'

这是我的代码:

 // use LINQ to fetch all the children textboxes
 System.Collections.Generic.Dictionary<string, string> dictionary = tabCtrl1.TabPages["tabPage1"].Controls.OfType<TextBox>()
     .Where(t => t.TabIndex >= startTabIndex && t.TabIndex <= endTabIndex && !string.IsNullOrWhiteSpace(t.Text))
     .OrderBy(f => f.TabIndex)
     .Select(x => new System.Collections.Generic.KeyValuePair<string, string>(x.Name, x.Text))
     .ToDictionary(z => z.Key, z => z.Value);

     // loop through all the children textboxes
     // and assign them to the list members.childTextBoxes
     foreach (System.Collections.Generic.KeyValuePair<string, string> kvp in dictionary)
     {
         members.childTextBoxes.Add(new System.Collections.Generic.KeyValuePair<string, string>($"{kvp.Key}", $"{kvp.Value}"));
     }

 var mapToDatabase = new System.Collections.Generic.Dictionary<string, string>();

 mapToDatabase.Add(nameof(textBoxChild1), "childName");
 mapToDatabase.Add(nameof(textBoxChild1Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild1Email), "childEmail");

 // child 2
 mapToDatabase.Add(nameof(textBoxChild2), "childName");
 mapToDatabase.Add(nameof(textBoxChild2Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild2Email), "childEmail");

 // child 3
 mapToDatabase.Add(nameof(textBoxChild3), "childName");
 mapToDatabase.Add(nameof(textBoxChild3Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild3Email), "childEmail");

 // child 4
 mapToDatabase.Add(nameof(textBoxChild4), "childName");
 mapToDatabase.Add(nameof(textBoxChild4Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild4Email), "childEmail");

 // child 5
 mapToDatabase.Add(nameof(textBoxChild5), "childName");
 mapToDatabase.Add(nameof(textBoxChild5Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild5Email), "childEmail");

 // child 6
 mapToDatabase.Add(nameof(textBoxChild6), "childName");
 mapToDatabase.Add(nameof(textBoxChild6Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild6Email), "childEmail");

 // child 7
 mapToDatabase.Add(nameof(textBoxChild7), "childName");
 mapToDatabase.Add(nameof(textBoxChild7Birthday), "birthday");
 mapToDatabase.Add(nameof(textBoxChild7Email), "childEmail");


 string fieldList = $"{string.Join(",", members.childTextBoxes.Select(tb => mapToDatabase[tb.Key]))}";
 string valueList = $"{string.Join(",", members.childTextBoxes.Select(tb => "?"))}";

 string insertQuery = $"INSERT INTO children (pid, {fieldList}) VALUES (?,{valueList})";



   using (members.DBCommand = new OleDbCommand(insertQuery, members.DBConnection))
   { 
        foreach (var field in members.childTextBoxes)
        {                       
           members.DBCommand.Parameters.AddWithValue("@pid", lastInsertId);
           members.DBCommand.Parameters.Add("@" + field.Key, OleDbType.LongVarChar).Value = field.Value;

            if (members.DBCommand.ExecuteNonQuery() > 0) // error line
            {                       
               members.DBCommand.Parameters.Clear();
            }
        }


        MessageBox.Show("Records inserted", "QBC", MessageBoxButtons.OK);

        // clear the fields
        foreach (Control c in Controls)
        {
            if (c is TextBox)
            {
               ((TextBox)c).Clear();
            }
        }
   }

我认为这与map.ToDatabase.Add()部分有关。有没有办法避免这种情况,仍然为每个填写的文本框字段执行插入查询?其他一切工作正常,我只是不能添加多个文本框行。

任何帮助都将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:0)

运行 members.DBCommand.ExecuteNonQuery()后,您需要在某处添加 members.DBCommand.Parameters.Clear()。您还应该在处理 members.childTextBoxes 字典项的for循环中调用 members.DBCommand.ExecuteNonQuery()函数。

通过清除参数集合,您正准备下一个查询。

这有帮助吗?

修改 至少可以说,你的方法有点不正统。但它可以工作。以下是一些指示:

  1. 手工构建您需要的DBCommand CommandText和Parameters,以便从textBoxChild1,textBox1Birthday,textBoxChild1EMail以及您需要的任何其他字段插入数据。一旦你开始工作,用textBoxChild2再做一次,看看有什么变化。构造循环,以便每次迭代根据需要调整插入查询和参数。

  2. 考虑远离textBoxChild1和childName字典映射的使用。而是创建一个Child对象,然后创建一个Child对象的通用列表(即List&lt; Child&gt;)。在该通用列表中,每个列表元素都是子对象。然后,您可以通过遍历列表来构建数据库操作。有很多示例说明如何在C#中迭代通用列表对象。

  3. 如果您的前端UI上有包含信息行的文本框,请改用网格。你不应该有一个textBoxChild1 UI元素和一个textBoxChild2元素 - 这是一个噩梦,特别是如果你需要添加一个新的Child7或Child8,或者你有更多的字段要为每个孩子添加。您需要找到一个适合集合和对象的设计,并相应地构造插入查询。

  4. 不要对自己太过刻苦。您的初始设计存在很大缺陷,我不建议仅仅因为您投入时间而保留它。应改变其设计的可读性和可维护性。

    希望这有帮助。