重复键值违反唯一约束(主键)

时间:2015-07-28 05:43:24

标签: c# checkedlistbox

您好我在这里有一个程序,它将checkedlistbox中的已检查值存储到数据库中。问题是我总是遇到一个异常,说'#34;重复键值违反了唯一约束pk_famcon。"我已经尝试了其他替代方案,但它总会最终导致这种情况。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Npgsql;

namespace WindowsFormsApplication1
{
    public partial class Form8 : Form
    {
        public Form8()
        {
            InitializeComponent();
            this.Load += Form8_Load;
            button1.Click += button1_Click;
        }

            DataSet ds = new DataSet();

        private void Form8_Load(object sender, EventArgs e)
        {
            Populate_DataSet();
            FillCheckListBox();
        }

        private void Populate_DataSet()
        {
            string connstring = "Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;";
            using (NpgsqlConnection conn = new NpgsqlConnection(connstring))
            {
                string conditionName = "SELECT * FROM condition";
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(conditionName, conn);
                da.Fill(ds, "conname");
                da.Fill(ds, "conid");
            }
        }

        private void FillCheckListBox()
        {
            DataRow row1 = null;
            int iRowCnt = 0;

            checkedListBox1.Items.Clear();

            foreach (DataRow row_1 in ds.Tables["conname"].Rows)
            {
                row1 = row_1;
                checkedListBox1.Items.Add(ds.Tables["conname"].Rows[iRowCnt][1]);
                iRowCnt = iRowCnt + 1;     
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Data has been saved");
          if (checkedListBox1.Items.Count > 0)
          {
              string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
              NpgsqlConnection conn = new NpgsqlConnection(connstring);
              conn.Open();

              for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
              {
                  NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
                  cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
                  cmd.ExecuteNonQuery();
                  string value = checkedListBox1.CheckedItems[i].ToString(); 
              }
              MessageBox.Show("Data has been saved");
              conn.Close();
          }

        }
    }
}

1 个答案:

答案 0 :(得分:2)

看看这个循环:

for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
    NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
    cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
    cmd.ExecuteNonQuery();
    string value = checkedListBox1.CheckedItems[i].ToString(); 
}

您在循环的每次迭代中将相同的值(checkedListBox1.Text)插入主键字段,通过它的声音。在最终语句之前,你没有使用i(循环中的索引) - 并且只是声明并给一个立即超出范围的局部变量赋值。我怀疑你的意思是:

for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
    NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
    string value = checkedListBox1.CheckedItems[i].ToString(); 
    cmd.Parameters.AddWithValue("@famcon", value);
    cmd.ExecuteNonQuery();
}

除此之外,还有其他一些值得改变的事情:

  • 循环条件将更常规地写为:

    for(int i = 0; i&lt; checkedListBox1.CheckedItems.Count; i ++)

...或使用foreach循环。

  • 每次都应使用using语句处理命令
  • 明确指定参数类型通常更清晰,然后使用Value属性设置参数值

把这些放在一起,你有:

foreach (var item in checkedListBox1.CheckedItems)
{
    using (var cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn)
    {
        cmd.Parameters.Add("@famcon", NpgsqlDbType.Varchar).Value = item.ToString();
        cmd.ExecuteNonQuery();
    }
}