简体   繁体   中英

C# MS Access database how to delete

I've tried searching for tutorials and none of them seems to get it to work, as of now my Delete button has no code for deleting from the database. I'll add any details you need for the problem.

My code for adding:

private void btnSaveAddAsset_Click(object sender, EventArgs e)
{
        if (txtAddFloor.Text == "" || txtAddRoom.Text == "" || string.IsNullOrWhiteSpace(txtAddFloor.Text) == true || string.IsNullOrWhiteSpace(txtAddRoom.Text) == true)
        {
            MessageBox.Show("Please enter valid information", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
        }
        else
        {
            con = new OleDbConnection("Provider=Microsoft.ACE.Oledb.12.0;Data Source =AssetManagement.accdb");
            Ds = new DataSet();


            ths.lstViewListOfRooms.Items.Add(txtAddFloor.Text).SubItems.Add(txtAddRoom.Text);

            String date = "dd/MM/yyyy - HH:mm:ss";
            ths.lstViewListOfRooms.Items[ths.lstViewListOfRooms.Items.Count - 1].SubItems.Add(txtAddDescriptionDetail.Text);
            ths.lstViewListOfRooms.Items[ths.lstViewListOfRooms.Items.Count - 1].SubItems.Add(DateTime.Now.ToString(date));


            string query = "INSERT INTO tbl_Assets(asset_floor, asset_room, asset_description, asset_createdOn)" + " VALUES (" + txtAddFloor.Text + "," + txtAddRoom.Text + ", '" + txtAddDescriptionDetail.Text + "' , '" + DateTime.Now.ToString(date) + "'" + ") ";
            con.Open();
            Da = new OleDbDataAdapter(query, con);
            Da.Fill(Ds, "tbl_Assets");
            con.Close();
            this.Close();
        }
}

Screenshots I took from my previous question Error in displaying MS Access Database in C#

Actually you would do the same procedure as in your insert command. The only problem is, that you would need to be able to uniquely identify the entry you want to delete. I am not sure about the structure of your tbl_Assets but i would assume, that it does have a unique ID field, that you can retrieve right after your insert. Getting, remembering (storing in memtable) and then using your unique IDs , is the main part to achieve, then you can just delete using your AssetID .

From the design point, i would not use the default OleDbDataAdapter, but rather create your own, and place all important and often used queries in there. So this would be one possible solution:

{
    ...

    // open db connection
    con.Open();

    // get our own asset adapter
    Da = new AssetAdapter(con);

    // create a DataTable and fill it.
    DataTable assets = new DataTable();
    Da.Fill(assets);

    // add a RowDeleted event handler for the table.
    assets.RowDeleted += new DataRowChangeEventHandler(row_deleted);

    . . . you could define handlers for update and insert as well . . .

    // insert a test record
    DataRow assetRow = assets.NewRow();
    assetRow["asset_floor"] = "15";
    assetRow["asset_room"] = "7c";

    . . . and so on . . .

    assets.Rows.Add(assetRow);

    // update database.
    Da.Update(assetRow);

    // now get the asset id of the new created asset
    Int32 assetID = (Int32)Da.InsertCommand.Parameters["@Identity"].Value;

    // now we can use this id to delete the row again
    DataRow found = assets.Rows.Find(assetID);

    if (found != null) 
    {
        // now delete row again
        assets.Rows.Delete(assetID);
        Da.Update(assets)
    }

    con.Close();

    this.Close();

    ...

}

/**
* AssetAdapter returns the database adapter for selecting and deleting
*/
public static OleDbDataAdapter AssetAdapter(OleDbConnection connection)
{
    OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
    OleDbCommand command;
    OleDbParameter parameter;

    /*
     * Here we create a command that selects assets by
     * floor and room. You can add more fields if needed.
     * Finally the command is set as the adapters *SelectCommand*
     */

    command = new OleDbCommand("SELECT asset_id FROM tbl_Assets " +
        "WHERE asset_floor = ? AND asset_room = ?", connection);

    // add the parameters floor and room
    // (assuming VarChar is your field type, change accordingly) 
    command.Parameters.Add("asset_floor", OleDbType.VarChar, 20);
    command.Parameters.Add("asset_room", OleDbType.VarChar, 20);

    // finally set the command to the adapters select command
    dataAdapter.SelectCommand = command;


    /*
     * Now we create a command that inserts assets by
     * filling the fields needed.
     * Then the command is set as the adapters *InsertCommand*
     */

    // Create the InsertCommand.
    command = new OleDbCommand(
        "INSERT INTO tbl_Assets (asset_floor, asset_room, asset_description, asset_createdOn) " +
        "VALUES (?, ?, ?, ?)", connection);

    // add the parameters
    command.Parameters.Add(
        "asset_floor", OleDbType.VarChar, 20, "asset_floor");
    command.Parameters.Add(
        "asset_room", OleDbType.VarChar, 20, "asset_room");
    command.Parameters.Add(
        "asset_description", OleDbType.VarChar, 128, "asset_description");
    command.Parameters.Add(
        "asset_createdOn", OleDbType.DateTime, 20, "asset_createdOn");

    // create an output parameter for the new identity value.
    parameter = command.Parameters.Add("@Identity", SqlDbType.Int, 0, "asset_id");
    parameter.Direction = ParameterDirection.Output;

    // now we set the command to the adapters insert
    adapter.InsertCommand = command;

    . . .

        // same procedure for UpdateCommand

    . . .


    /*
     * Here we create a command that deletes assets by
     * asset_id. You can add more fields if needed.
     * Finally the command is set as the adapters *DeleteCommand*
     */

    // Create the DeleteCommand.
    command = new OleDbCommand(
        "DELETE * FROM tbl_Assets WHERE asset_id = ?", 
        connection);

    parameter = command.Parameters.Add(
        "asset_id", OleDbType.Char, 5, "asset_id");
    parameter.SourceVersion = DataRowVersion.Original;

    dataAdapter.DeleteCommand = command;

    return dataAdapter;
}

// event handler which is called when row is deleted
private static void row_deleted(object sender, DataRowChangeEventArgs e)
{
    Console.WriteLine("Row was DELETED event: name={0}/{1}; action={2}", 
        e.Row["asset_floor", DataRowVersion.Original], 
        e.Row["asset_room", DataRowVersion.Original], 
        e.Action);
}

This way you should have a clean solution and a shareable object which only defines queries once at one place. But typical Microsoft coding... your code keeps growing and growing and in the end you have an untamable monster.

BEWARE i have written this out of my head, it is untested, but is should pretty much run or push you the right way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM