C# - значение вставки SQL и идентификатор флажка из списка CheckboxList
Проблема:
Я заполняю список флажков из таблицы SQL:
public static List<string> populateCheckBoxes(string type)
{
List<string> items = new List<string>();
items.Add("");
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand sqlcmd;
switch (type)
{
case "referralorsignposting":
sqlcmd = new SqlCommand("SELECT * FROM SWApp_List_Equipment WHERE type = 'Referral or Signposting' ORDER BY order_no, name", conn);
break;
case "actionstaken":
sqlcmd = new SqlCommand("SELECT * FROM SWApp_List_Equipment WHERE type = 'Actions Taken' ORDER BY order_no, name", conn);
break;
default:
sqlcmd = new SqlCommand("SELECT * FROM SWApp_List_Equipment", conn);
break;
}
SqlDataAdapter da = new SqlDataAdapter(sqlcmd);
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
items.Add(dr["name"].ToString());
CheckboxIDRecord = dr["id"].ToString();
//items.Add(dr["VisitTime"] + " " + dr["PropPostcode"]);
}
return items;
}
Я перебрал каждое значение, выбранное в "контрольном списке", и это вставляет каждое выбранное значение:
foreach (var item in saw.actionsTakenCheckBoxList)
{ //ADD ACTIONS AND REFERRAL
SqlCommand add = new SqlCommand("INSERT INTO SWApp_CheckboxAnswers (SW_ID, Checkbox_ID, Checkbox_Section, Checkbox_Type, Checkbox_Answer) VALUES(@SW_ID,@Checkbox_ID,@Checkbox_Section,@Checkbox_Type,@Checkbox_Answer) ");
add.CommandType = CommandType.Text;
add.Connection = sqlcon;
add.Parameters.AddWithValue("@SW_ID", "");
add.Parameters.AddWithValue("@Checkbox_ID", "");
add.Parameters.AddWithValue("@Checkbox_Section", "");
add.Parameters.AddWithValue("@Checkbox_Type", "");
add.Parameters.AddWithValue("@Checkbox_Answer", "");
add.Parameters["@SW_ID"].Value = saw.EntryID.ToString();
add.Parameters["@Checkbox_ID"].Value = CheckboxIDRecord.ToString();
add.Parameters["@Checkbox_Section"].Value = "SmokeDetectionReferral";
add.Parameters["@Checkbox_Type"].Value = "";
add.Parameters["@Checkbox_Answer"].Value = item.ToString();
sqlcon.Open();
add.ExecuteNonQuery();
sqlcon.Close();
}
Как вы можете видеть, то, что я пробовал в настоящее время, только вводит идентификатор для первого значения, выбранного в Checkboxlist.
Цель:
Цель состоит в том, чтобы вставить значение флажка "name", а также "id" каждого элемента.
Исследование:
Я попытался следовать этой статье, чтобы поместить элементы в массив, но в итоге получил "Массив вышел за пределы индекса", что привело меня ко второй статье.
Передача элементов из контрольного списка в таблицу SQL Server
Индекс вышел за пределы массива? C# формы
Буду признателен за любые указания с этим. Благодарю.
2 ответа
Я реализовал словарь для элементов, которые будут помещены в контрольный список. Это позволяет мне использовать значение в элементах флажка, а затем использовать ключ в INSERT для базы данных SQL.
Dictionary<string, string> referral = new Dictionary<string, string>();
При загрузке формы заполните список флажков элементами из словаря.
private void Section3_Load(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("select Id, name from SWApp_List_Equipment WHERE type = 'referral or signposting' ORDER BY order_no,name", conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
referral.Add(dr["id"].ToString(), dr["name"].ToString());
}
}
foreach (KeyValuePair<string, string> refs in referral)
{
box = new CheckBox();
box.Text = refs.Value.ToString();
actionsTakenCheckBoxList.Items.Add(box.Text);
box.CheckedChanged += new EventHandler(this.CheckedChange);
}
}
Вставьте значения в таблицу на кнопке закрытия формы.
private void closeButton_Click(object sender, EventArgs e)
{
using (SqlConnection sqlcon = new SqlConnection(connectionString)) {
//summary
foreach (var item in actionsTakenCheckBoxList.CheckedItems.OfType<string>().ToList())
{
//ADD ACTIONS AND REFERRAL
SqlCommand add = new SqlCommand("INSERT INTO SWApp_CheckboxAnswers (SW_ID, Checkbox_ID, Checkbox_Section, Checkbox_Type, Checkbox_Answer) VALUES(@SW_ID,@Checkbox_ID,@Checkbox_Section,@Checkbox_Type,@Checkbox_Answer) ");
add.CommandType = CommandType.Text;
add.Connection = sqlcon;
add.Parameters.AddWithValue("@SW_ID", "");
add.Parameters.AddWithValue("@Checkbox_ID", "");
add.Parameters.AddWithValue("@Checkbox_Section", "");
add.Parameters.AddWithValue("@Checkbox_Type", "");
add.Parameters.AddWithValue("@Checkbox_Answer", "");
add.Parameters["@SW_ID"].Value = entry.entryID.ToString();
var myKey = referral.FirstOrDefault(x => x.Value == item.ToString()).Key;
add.Parameters["@Checkbox_ID"].Value = myKey;
add.Parameters["@Checkbox_Section"].Value = "SmokeDetection";
add.Parameters["@Checkbox_Type"].Value = "Referral";
add.Parameters["@Checkbox_Answer"].Value = item.ToString();
sqlcon.Open();
add.ExecuteNonQuery();
sqlcon.Close();
}
}
}
Я вижу несколько проблем, вместо того, чтобы попытаться исправить их здесь, это предложение о том, как решить эту проблему.
Общую картину можно увидеть в моем примере кода MSDN на CheckedListBox и SQL-Server, который включает в себя сценарий sql для генерации базы данных и данных.
https://code.msdn.microsoft.com/Working-with-CheckedListBox-3b765442?redir=0
Взятый по ссылке выше в Operations.cs, этот метод получает наши данные (следующий блок кода заполняет CheckedListBox)
/// <summary>
/// Get all records to show in the CheckedListBox
/// </summary>
/// <returns></returns>
public DataTable GetAll()
{
var dt = new DataTable();
using (SqlConnection cn = new SqlConnection { ConnectionString = ConnectionString })
{
using (SqlCommand cmd = new SqlCommand { Connection = cn })
{
cmd.CommandText = "SELECT id, Description, Quantity, CheckedStatus FROM Products ---WHERE (Quantity > 0)";
cn.Open();
dt.Load(cmd.ExecuteReader());
}
}
return dt;
}
Код формы
/// <summary>
/// Load CheckedListBox from database table
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
var ops = new Operations();
// read data from database table
var dt = ops.GetAll();
int LastIndex = 0;
/*
* Here we iterate the rows in the DataTable while in
* CoursesCodeSample I set the DataSource of the CheckedListBox
* to the DataTable. The method shown here has always been the
* way to go as many indicated that since the DataSource property
* of the CheckedListBox is not documented it could go away, well
* many years later it's still here so guess what, it's okay.
*/
foreach (DataRow row in dt.Rows)
{
checkedListBox1.Items.Add(new CheckListBoxItem()
{
Description = row.Field<string>("Description"),
PrimaryKey = row.Field<int>("id"),
Quantity = row.Field<int>("Quantity"),
IsDirty = false
});
LastIndex = checkedListBox1.Items.Count - 1;
checkedListBox1.SetItemChecked(LastIndex, row.Field<bool>("CheckedStatus"));
}
checkedListBox1.ItemCheck += CheckedListBox1_ItemCheck;
}
Из Opertions.cs - метод вставки
public void Insert(List<CheckListBoxItem> items)
{
// optionally used for obtaining new primary key
//int newIdentifier;
using (SqlConnection cn = new SqlConnection { ConnectionString = ConnectionString })
{
using (SqlCommand cmd = new SqlCommand { Connection = cn })
{
// uncomment ending select statement and use commented to get new primary key
cmd.CommandText = "INSERT INTO Products " +
"([Description],Quantity,CheckedStatus) " +
"VALUES (@Description,@Quantity,@CheckedStatus); " +
"-- SELECT CAST(scope_identity() AS int);";
cmd.Parameters.Add(new SqlParameter()
{ ParameterName = "@Description", SqlDbType = SqlDbType.NVarChar });
cmd.Parameters.Add(new SqlParameter()
{ ParameterName = "@Quantity", SqlDbType = SqlDbType.Int });
cmd.Parameters.Add(new SqlParameter()
{ ParameterName = "@CheckedStatus", SqlDbType = SqlDbType.Bit });
cmd.Parameters.Add(new SqlParameter()
{ ParameterName = "@CategoryIdentifier", SqlDbType = SqlDbType.Int });
cn.Open();
foreach (CheckListBoxItem item in items)
{
cmd.Parameters["@Description"].Value = item.Description;
cmd.Parameters["@Quantity"].Value = item.Quantity;
cmd.Parameters["@CheckedStatus"].Value = item.Checked;
//newIdentifier = (int)cmd.ExecuteNonQuery();
if ((int)cmd.ExecuteNonQuery() > -1)
{
// inserted
}
else
{
// failed
}
}
}
}
}
Вышесказанное является основным, закомментированный код показывает (при необходимости), как получить новый первичный ключ.
Вызовите метод выше
private void iterateButton_Click(object sender, EventArgs e)
{
var items = new List<CheckListBoxItem>();
for (int index = 0; index < checkedListBox1.Items.Count; index++)
{
if (((CheckListBoxItem)checkedListBox1.Items[index]).IsDirty)
{
items.Add(new CheckListBoxItem()
{
PrimaryKey = ((CheckListBoxItem)checkedListBox1.Items[index]).PrimaryKey,
Checked = checkedListBox1.GetItemChecked(index),
Description = ((CheckListBoxItem)checkedListBox1.Items[index]).Description
});
}
}
if (items.Count >0)
{
Ops.Insert(items);
}
}
Наконец, класс, используемый для заполнения CheckedListBox
namespace CheckListBoxFromSQL_Server
{
public class CheckListBoxItem
{
/// <summary>
/// Identifier for database table
/// </summary>
public int PrimaryKey;
/// <summary>
/// Display member for CheckedListBox and a field in the table
/// </summary>
public string Description;
public int Quantity;
/// <summary>
/// Indicates the checked state in the database table and for setting a Checked item in the CheckedListbox
/// </summary>
public bool Checked;
/// <summary>
/// Used to determine if a item changed after loaded in the CheckedListBox
/// </summary>
public bool IsDirty;
public override string ToString() { return Description; }
}
}
Надеюсь, это полезно