VS重启后SQL更改消失

我正在学习C#和SQL交互的基础知识,我有这样的forms:

在此处输入图像描述

它显示了使用VS 2013 DB构建器制作的预填充数据库中的值,并且所有内容在上部按钮上都能正常工作

这是我的表:

在此处输入图像描述

问题:

  • 单击“添加”时,文本框将被清除;
  • 接下来,填写文本框,当我单击Save时,记录显然已添加到DB(或至少添加到DataSet?),因为它给了我一条成功的消息,并在我使用上方按钮浏览DB时显示;
  • 如果我关闭并重新打开我的应用程序(不关闭VS) ,我插入的记录仍然存在
  • 但如果我关闭并重新打开VS并再次运行我的应用程序,我输入的记录就不见了
  • 此外,如果我没有关闭VS,如果我转到服务器资源管理器(VS左窗格),请单击我的表=>显示表数据,新记录永远不会出现。

这是Form1.cs代码:

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; namespace SQLtest { ///  /// A class that constains our form ///  public partial class Form1 : Form { // variables DBconnection objConnect; string conString; DataSet ds; DataRow dr; int maxRows; int inc = 0; ///  /// Constructor of the class ///  public Form1() { InitializeComponent(); } ///  /// Form initialization method ///  ///  ///  private void Form1_Load(object sender, EventArgs e) { try { objConnect = new DBconnection(); conString = Properties.Settings.Default.TestConnectionString; objConnect.connection_string = conString; objConnect.Sql = Properties.Settings.Default.SQL; ds = objConnect.GetConnection; maxRows = ds.Tables[0].Rows.Count; // MessageBox.Show("Max Rows: " + maxRows); NavigateRecords(); } catch (Exception err) { MessageBox.Show(err.Message); } } // DB Navigation Methods ///  /// Sets pointer (inc) to last row ///  ///  ///  private void btnNext_Click(object sender, EventArgs e) { // prevent indexOutOfBounds error if (inc != maxRows - 1) { inc++; NavigateRecords(); } else { MessageBox.Show("Reached last employee. Showing the first record."); inc = 0; NavigateRecords(); } } ///  /// Sets pointer (inc) to previous row (if possible) ///  ///  ///  private void btnPrevious_Click(object sender, EventArgs e) { // prevent indexOutOfBounds error if (inc != 0) { inc--; NavigateRecords(); } else { MessageBox.Show("Reached first employee. Showing the last record."); inc = maxRows - 1; NavigateRecords(); } } ///  /// Sets pointer (inc) to first row ///  ///  ///  private void btnFirst_Click(object sender, EventArgs e) { if (inc != 0) { inc = 0; NavigateRecords(); } else { MessageBox.Show("Already on first employee."); } } ///  /// Sets pointer (inc) to last row ///  ///  ///  private void btnLast_Click(object sender, EventArgs e) { if (inc != maxRows - 1) { inc = maxRows - 1; NavigateRecords(); } else { MessageBox.Show("Already on last employee."); } } ///  /// Main Navigation Method ///  private void NavigateRecords() { dr = ds.Tables[0].Rows[inc]; txtFirstName.Text = dr.ItemArray.GetValue(1).ToString(); txtLastName.Text = dr.ItemArray.GetValue(2).ToString(); txtJobTitle.Text = dr.ItemArray.GetValue(3).ToString(); txtDepartment.Text = dr.ItemArray.GetValue(4).ToString(); } ///  /// Exit button handler ///  ///  ///  private void btnExit_Click(object sender, EventArgs e) { Application.Exit(); } ///  /// Add new record Button. Simply clears text fields, ready for a new record to be added. ///  ///  ///  private void btnAddNew_Click(object sender, EventArgs e) { txtFirstName.Clear(); txtLastName.Clear(); txtJobTitle.Clear(); txtDepartment.Clear(); btnAddNew.Enabled = false; btnSave.Enabled = true; btnCancel.Enabled = true; } ///  /// Save a new record button ///  ///  ///  private void btnSave_Click(object sender, EventArgs e) { DataRow newRow = ds.Tables[0].NewRow(); // newRow[0] is the id, thus its filled automatically newRow[1] = txtFirstName.Text; newRow[2] = txtLastName.Text; newRow[3] = txtJobTitle.Text; newRow[4] = txtDepartment.Text; ds.Tables[0].Rows.Add(newRow); try { objConnect.UpdateDB(ds); maxRows++; inc = maxRows - 1; MessageBox.Show("DB updated successfully"); } catch (Exception err) { MessageBox.Show(err.Message); } btnAddNew.Enabled = true; btnSave.Enabled = false; btnCancel.Enabled = false; } ///  /// Cancel new record button. Simply call NavigateRecords() method, and restores buttons. ///  ///  ///  private void btnCancel_Click(object sender, EventArgs e) { NavigateRecords(); btnAddNew.Enabled = true; btnSave.Enabled = false; btnCancel.Enabled = false; } } } 

这是DBconnection.cs代码:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SQLtest { ///  /// A class that makes the connection to the SQL Database ///  class DBconnection { // variables private string sql_string; private string strCon; System.Data.SqlClient.SqlDataAdapter da_1; // set methods public string Sql { set { sql_string = value; } } public string connection_string { set { strCon = value; } } // DataSet public System.Data.DataSet GetConnection { get { return MyDataSet(); } } // MyDataSet method private System.Data.DataSet MyDataSet() { System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(strCon); con.Open(); da_1 = new System.Data.SqlClient.SqlDataAdapter(sql_string, con); System.Data.DataSet dat_set = new System.Data.DataSet(); da_1.Fill(dat_set,"Table_Data_1"); con.Close(); return dat_set; } // Update DB method public void UpdateDB(System.Data.DataSet ds) { System.Data.SqlClient.SqlCommandBuilder cb = new System.Data.SqlClient.SqlCommandBuilder(da_1); cb.DataAdapter.Update(ds.Tables[0]); } } } 

编辑:

为了测试VS将DB.mdf复制到“/ bin / Debug”文件夹,我添加了一条新记录,然后从服务器资源管理器中分离了数据库,并从“/ bin / Debug”文件夹复制了DB.mdf并替换了主数据库上的DB.mdf项目文件夹。 它确认这可能是问题,因为现在我可以通过VS DB Designer看到新添加的记录。

现在我只需要弄清楚如何将对“/ bin / Debug”文件夹中的DB.mdf所做的更改更新到VS shutdown上的主项目DB.mdf。

请注意,运行程序会将数据库从根项目文件夹复制到Release或Debug文件夹,因此每次运行程序时,您都将使用数据库的新副本。 这意味着下次运行应用程序时,对您所创建的数据库的任何修改都将被覆盖并丢弃。 当您刚开发应用程序时,这很好。 如果您不想要此行为,请在“解决方案资源管理器”中选择数据库文件(.mdf),然后在“属性”窗口中找到“复制到输出目录”选项。 如果更新,则将其值更改为“复制”。 现在,只有在输出目录中已存在的较新版本的项目根目录中的数据库文件才会被映射。

显然,当您首次创建解决方案/项目数据库时,它将在项目的父目录中创建。 之后,当您构建/调试解决方案时,它会在Bin / Debug目录中添加数据库。 调试时对数据所做的任何更改都在Debug数据库中进行。 但是,当您每次在VS中运行应用程序时,它会从父目录中提取数据,该数据从未收到您在调试时所做的更改,因为这些更改实际上是在Debug数据库中进行的。

解:

  • 在数据库浏览器中
  • 右键单击数据库
  • 选择修改连接
  • 高级选项
  • 搜索属性AttachDbFileName
  • 从调试文件夹c:… \ bin \ debug \ DB.mdf将其更改为DB
  • 将数据库指向Debug目录后,在VS Server Explorer中,您可以删除解决方案资源管理器中的数据库,所有更新都将在Debug数据库中发生。