C# windows application access database data doesn&

2020-04-11 05:15发布

问题:

I'm creating a windows application using C# whereby I'm accessing an empty Access database which contains two tables: Provinces and Locations. I'm working on the form that just deals with the Provinces table which looks like this:

This is a subform. When it is open, I can insert/update records etc. Whenever I make a change, I click on the Load Table button to display the changes in the DataGridView object.

If I close this subform and show it again, I can click on the Load Table button and recall all the data for display in the DataGridView object. However, if I close down the application altogether, then I lose all my data. I prove this by double clicking the database file to launch it in Access where I can see that the data is definitely gone. This has become a mystery as I can't figure out why the data doesn't persist in the file. Please advise.

Below is the code for the form. You can see from my methods that I'm careful to close the connection object each and every time I perform a function. So I'm at a loss as to why I keep losing the data on application close?

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

namespace GTI_Taxi_Pricing
{
public partial class frmProv : Form
{
    private OleDbConnection connection = new OleDbConnection();
    public frmProv()
    {
        InitializeComponent();
        connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TaxiDB.accdb;Persist Security Info=False;";                
    }

    private void btnLoad_Click(object sender, EventArgs e)
    {
        try
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            String query = "SELECT * FROM Provinces;";
            command.CommandText = query;
            OleDbDataAdapter da = new OleDbDataAdapter(command);
            DataTable dt = new DataTable();
            da.Fill(dt);
            dataGridView1.DataSource = dt;
            connection.Close();
        }
        catch(Exception ex)
        {
            MessageBox.Show("Error: " + ex);
        }
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        if (txtName.Text == "")
        {
            MessageBox.Show("The name field must have a value.");
            return;
        }
        try
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = "INSERT INTO Provinces (name) VALUES ('" + txtName.Text + "')";

            command.ExecuteNonQuery();
            MessageBox.Show("Data Saved");
            connection.Close();
        }
        catch(Exception ex)
        {
            MessageBox.Show("Error: " + ex);
        }
    }

    private void btnNewRecord_Click(object sender, EventArgs e)
    {
        txtID.Text = "";
        txtName.Text = "";
    }

    private void btnEdit_Click(object sender, EventArgs e)
    {
        if (txtID.Text == "")
        {
            MessageBox.Show("The id field must have a value.");
            return;
        }
        if(txtName.Text == "")
        {
            MessageBox.Show("The name field must have a value.");
            return;
        }
        try
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = "UPDATE Provinces SET name='" + txtName.Text + "' WHERE id=" + txtID.Text + ";";

            command.ExecuteNonQuery();
            MessageBox.Show("Data Update Successful.");
            connection.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex);
        }
    }

    private void btnDelete_Click(object sender, EventArgs e)
    {
        if (txtID.Text == "")
        {
            MessageBox.Show("The id field must have a value.");
            return;
        }
        try
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = "DELETE FROM Provinces WHERE id=" + txtID.Text + ";";

            command.ExecuteNonQuery();
            MessageBox.Show("Record Deleted Successfully.");
            connection.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex);
        }
    }

    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if(e.RowIndex >= 0)
        {
            DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
            txtID.Text = row.Cells[0].Value.ToString();
            txtName.Text = row.Cells[1].Value.ToString();
        }
    }
}

}

回答1:

This is a common scenario with file based database (or attached database files)
Your connection string refers to the database without using any path.
This means that your database is located in the same directory where your application runs.
You don't have any problem inserting, modifying or deleting data but you loose everything when you restart the app from INSIDE a Visual Studio Debug Session.

Now, if you look at your project files you probably have the database file listed between the other files. Between the properties of this database file you will notice the property Copy to the Output directory and its value set to Copy Always.

This means that every time you restart your application from inside the Visual Studio environment that file is copied from the project folder to the output directory (usually BIN\DEBUG or BIN\x86\DEBUG) but this destroys the database used in the previous run removing the data inserted modified or deleted

Change the property Copy to Output Directory to Copy Never or Copy if Newer

However Copy If Newer presents another problem with MS-Access. If you open the database file located in your project directory using Access o using the Server Connection window of Visual Studio the file is immediately modified also if you don't change anything and thus the Copy If Newer will execute the copy to the output directory