C# C绑定值与数据库不匹配

C# C绑定值与数据库不匹配,c#,sql-server,C#,Sql Server,VS2010表格申请表 我有一个带有SQLServer数据库.mdf文件的C项目,该文件包含一个ID字段,数据类型为int,不允许为null;这样它就可以自动编号了 在我的主窗体中,我将表绑定到bindingsource,将ID字段绑定到标签 所有表单控件及其绑定属性都是在“属性”窗口中创建的,没有代码 表单包括一个bindingnavigator,它有一个+按钮add记录。 单击+按钮的瞬间,ID字段的值为-1;可能是一个临时值,但这是自动发生的,没有任何代码隐藏 然后,当我将绑定控件中的所有

VS2010表格申请表

我有一个带有SQLServer数据库.mdf文件的C项目,该文件包含一个ID字段,数据类型为int,不允许为null;这样它就可以自动编号了

在我的主窗体中,我将表绑定到bindingsource,将ID字段绑定到标签

所有表单控件及其绑定属性都是在“属性”窗口中创建的,没有代码

表单包括一个bindingnavigator,它有一个+按钮add记录。 单击+按钮的瞬间,ID字段的值为-1;可能是一个临时值,但这是自动发生的,没有任何代码隐藏

然后,当我将绑定控件中的所有值插入数据库中它们各自的列时,这段代码工作正常,除了由数据库自动递增int自动分配的ID。 这就是绑定控件中的值与数据库中存储的值不匹配的原因

这使我无法继续创建通过引用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();
        }
    }
}

以下是我所看到的问题:

您正在将数据集绑定到应用程序中的控件。单击+按钮,该按钮在数据集中生成新行,并指定默认Id-1。然后通过insertNewContact手动插入该数据,但实际上从未检索数据库颁发的Id并将其应用于数据集。如果数据集中Id字段的值仍然为-1,则重置绑定多少次并不重要,也不需要从数据库刷新数据集

你可以用多种方法中的一种。您只需在insertNewContact之后调用fillContactGrid即可。或者,您可以在查询结束时选择@@identity并手动更新数据集。为此,您需要将数据库调用更改为command.ExecuteScalar

无论如何,您都需要从数据库中检索新插入的Id,并更新数据集中的相应行

如果我没记错的话,已经有一段时间了。仅供参考,这有点老套,但它展示了以下概念:

添加:sqlCmd+=@;选择@标识

更改:

int rows = command.ExecuteNonQuery();
致:


花了一段时间,但最终找到了问题/解决方案

在FormMain上,VisualStudio添加了一行来填充我将控件绑定到BindingSource时创建的数据适配器

this.contactInfoTableAdapter.Fillthis.contactsDataSet.ContactInfo

在完成命令后添加这行代码。ExecuteOnQuery刷新了绑定控件中的数据,ID值-1被SQLServer指定的正确值替换


非常感谢布莱恩。我从你的帮助中学到了很多新东西,我相信这对我将来会有好处。

你能发布导致异常的代码吗?contactInfoBindingSource.DataSource=null;无法绑定到数据源上的属性或列ID。请编辑问题并插入该代码,同时插入周围的代码,以便其他用户了解您的操作-以此处发布的代码量为例:我拥有的代码不是问题所在,问题是绑定到ID列的标签中的值与存储在数据库ID列中的实际值不匹配。我需要代码来纠正这一点,但我在类似帖子中找到的建议都不起作用。选中的答案表示将DataSource设置为null,但如上所述,这将抛出并接受.fillContactGrid;在我的代码的最底层。网格在更新时确实包含ID的正确值,但这是因为它是由查询填充的,而不是绑定的。我不确定您希望绑定做什么。在执行插入后,您必须更新数据集中的适当字段,如果您这样做,绑定将更新。对于您的第二个建议,我不知道如何实现。如果你有时间提供更多的细节,我会很高兴,同时我会尝试按照你的建议自己。谢谢绑定只是在ui控件和数据集之间进行的。您的数据集和数据库之间没有绑定,这实际上并不存在。因此,如果您手动更新数据库(这就是您正在做的),您的数据集不知道数据库中的数据已更改。是的,我得到了…这就是我希望BindingSource.ResetBindi的原因
ng方法开始工作,但它什么也没做。ResetBinding被称为解决之前几个类似问题的方法,但没有一个表明该方法确实有效……不幸的是,这样做可以有效地重新查询整个数据集。这不是最好的案例,但我很高兴它起作用了。
int newid = (int)command.ExecuteScalar();
((DataSet)contactsGridView.DataSource).Tables["ContactInfo"].Select("Id = -1")[0].SetField("Id", newId);