C#VS2010表单应用程序
我有一个带有SQL Server数据库(.mdf
文件)的C#项目,其中包含一个ID字段,数据类型为int,不允许空值;所以它是自动编号。
在我的主窗体中,我将表绑定到bindingsource,ID字段绑定到标签。
它们的所有表单控件和绑定属性都是在没有代码的情况下在属性窗口中完成的。
表单包含一个bindingnavigator,它有一个+按钮(添加记录)。 单击+按钮的瞬间,将值-1分配给ID字段;可能是一个临时值,但这种情况会自动发生而不会有任何代码。
然后当我将绑定控件中的所有值插入到它们各自的数据库列中时(此代码工作正常),除了由数据库自动分配的ID(自动递增int)。 因此,这就是绑定控件中的值与存储在数据库中的值不匹配的原因。
这阻止我继续创建一个通过引用ID字段来删除记录的方法,因为绑定控件中的值(-1)无效,即数据库中不存在这样的记录。
我已尝试BindingSource.ResetBindings
方法并刷新标签,但在退出并重新启动程序之前,该值仍为-1。
我还发现了尝试将BindingSource.DataSource
设置为null然后重新绑定的建议,但尝试将datasource或datamember设置为null会引发异常。我发现另一个建议将BindingSource.RaiseListChangedEvents
设置为false,但异常仍然发生。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Address_Book
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
//***Program Execution***
fillContactGrid();
}
private void fillContactGrid()
//This method retrieves and displays all records from ContactInfo
{
//Create a connection to the database
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ContactsConnectionString))
{
//Construct the SQL Query string
string sqlQuery = "SELECT * FROM ContactInfo";
//Open the connection
connection.Open();
//Pass the query to the database and receive dataset
SqlDataAdapter dataadapter = new SqlDataAdapter(sqlQuery, connection);
DataSet ds = new DataSet();
dataadapter.Fill(ds, "ContactInfo");
//Close the connection
connection.Close();
//Load the dataset into GridView
contactsGridView.DataSource = ds;
contactsGridView.DataMember = "ContactInfo";
}
}
private void FormMain_Load(object sender, EventArgs e)
{
//Initialize contactsDataSet
this.contactInfoTableAdapter.Fill(this.contactsDataSet.ContactInfo);
}
private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e)
{
disableNavigation();
//Show save and cancel buttons
buttonSave.Visible = true;
buttonCancel.Visible = true;
}
private void disableNavigation()
{
//Temporarily disable navigator controls
bindingNavigatorAddNewItem.Enabled = false;
bindingNavigatorDeleteItem.Enabled = false;
bindingNavigatorPositionItem.Enabled = false;
bindingNavigatorMoveFirstItem.Enabled = false;
bindingNavigatorMoveLastItem.Enabled = false;
bindingNavigatorMoveNextItem.Enabled = false;
bindingNavigatorMovePreviousItem.Enabled = false;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
//Cancel new record entry
contactInfoBindingSource.RemoveCurrent();
//Hide save and cancel buttons
buttonSave.Visible = false;
buttonCancel.Visible = false;
enableNavigation();
}
private void enableNavigation()
{
//Enable navigator controls
bindingNavigatorAddNewItem.Enabled = true;
bindingNavigatorDeleteItem.Enabled = true;
bindingNavigatorPositionItem.Enabled = true;
bindingNavigatorMoveFirstItem.Enabled = true;
bindingNavigatorMoveLastItem.Enabled = true;
bindingNavigatorMoveNextItem.Enabled = true;
bindingNavigatorMovePreviousItem.Enabled = true;
}
private void buttonSave_Click(object sender, EventArgs e)
{
insertNewContact();
}
private void insertNewContact()
{
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ContactsConnectionString))
{
//***Construct the SQL Command string
//Format: INSERT INTO table_name (column1,column2,column3,...) VALUES (value1,value2,value3,...)
//Command
string sqlCmd = "INSERT INTO ";
//Table name
sqlCmd += @"ContactInfo ";
//Column names
sqlCmd += @"(LastName, ";
sqlCmd += @"FirstName, ";
sqlCmd += @"Relationship, ";
sqlCmd += @"Title, ";
sqlCmd += @"Company, ";
sqlCmd += @"OfficePhone, ";
sqlCmd += @"OfficeExtension, ";
sqlCmd += @"CellPhone, ";
sqlCmd += @"HomePhone, ";
sqlCmd += @"Email1, ";
sqlCmd += @"Email2) ";
//Values
sqlCmd += @"VALUES ";
sqlCmd += @"(@LastName, ";
sqlCmd += @"@FirstName, ";
sqlCmd += @"@Relationship, ";
sqlCmd += @"@Title, ";
sqlCmd += @"@Company, ";
sqlCmd += @"@OfficePhone, ";
sqlCmd += @"@OfficeExtension, ";
sqlCmd += @"@CellPhone, ";
sqlCmd += @"@HomePhone, ";
sqlCmd += @"@Email1, ";
sqlCmd += @"@Email2)";
//Open the connection
connection.Open();
//Pass the command to the database
using (SqlCommand command =new SqlCommand(sqlCmd, connection))
{
command.Parameters.Add("@LastName", SqlDbType.NChar).Value = textLastName.Text;
command.Parameters.Add("@FirstName", SqlDbType.NChar).Value = textFirstName.Text;
command.Parameters.Add("@Relationship", SqlDbType.NChar).Value = textRelationship.Text;
command.Parameters.Add("@Title", SqlDbType.NChar).Value = textTitle.Text;
command.Parameters.Add("@Company", SqlDbType.NChar).Value = textCompany.Text;
command.Parameters.Add("@OfficePhone", SqlDbType.NChar).Value = textOfficePhone.Text;
command.Parameters.Add("@OfficeExtension", SqlDbType.NChar).Value = textOfficeExtension.Text;
command.Parameters.Add("@CellPhone", SqlDbType.NChar).Value = textCellPhone.Text;
command.Parameters.Add("@HomePhone", SqlDbType.NChar).Value = textHomePhone.Text;
command.Parameters.Add("@Email1", SqlDbType.NChar).Value = textEmail1.Text;
command.Parameters.Add("@Email2", SqlDbType.NChar).Value = textEmail2.Text;
try
{
int rows = command.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
connection.Close();
buttonSave.Visible = false;
buttonCancel.Visible = false;
enableNavigation();
}
}
private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
//Update the binding grid when its tab is selected
fillContactGrid();
}
}
}
答案 0 :(得分:0)
这是我能看到的问题:
您正在将数据集绑定到应用程序中的控件。单击“+”按钮可在数据集中生成新行,并指定Id
的默认-1
。然后,您通过insertNewContact
手动插入该数据,但是您实际上从未检索过发布的数据库Id
并将其应用于您的数据集。如果数据集中Id字段的值仍为-1
,则重置绑定的次数无关紧要,也不会从数据库刷新数据集。
您可以通过多种方式之一完成此操作。您只需在fillContactGrid
之后致电insertNewContact
即可。或者您可以在查询结束时select @@identity
并手动更新数据集。为此,您需要将数据库调用更改为command.ExecuteScalar()
。
无论哪种方式,您都需要从数据库中检索新插入的Id,并更新数据集中的相应行。
如果我的记忆对我有用(已经有一段时间了)。仅供参考,这有点像hackish,但它证明了这个概念:
添加:sqlCmd += @"; select @@identity";
更改:
int rows = command.ExecuteNonQuery();
为:
int newid = (int)command.ExecuteScalar();
((DataSet)contactsGridView.DataSource).Tables["ContactInfo"].Select("Id = -1")[0].SetField("Id", newId);
答案 1 :(得分:0)
花了一段时间,但终于找到了问题/解决方案。
在FormMain_Load上,Visual Studio添加了一行来填充将绑定控件绑定到BindingSource时创建的数据适配器;
this.contactInfoTableAdapter.Fill(this.contactsDataSet.ContactInfo);
完成命令后添加以下代码行.ExecuteNonQuery刷新绑定控件中的数据,并将SQL值-1替换为SQLServer分配的正确值。
非常感谢Brian。我从你的帮助中学到了很多新东西,我相信将来会对我有所帮助。