Update And Delete

Mar 10, 2011 at 10:11 PM
Edited Mar 10, 2011 at 10:14 PM

Ok, this is annoying to post (since it's so basic). But I have a form which receives a Client object, displays the relevant data in textboxes. Now I want to update or delete that single row. I cannot find how to do it, without getting a couple of errors. The most annoying thing of all is that I can't find an example on the net.

EDIT: is it possible to get an item in a constructor, add it to a collection, do a number of inserts, updates and deletes and then persist that single collection? And how would I do that?

Coordinator
Mar 11, 2011 at 2:48 AM

I assume that you are using the ADO.NET DAL because if you were using the Entity Framework DAL you could find many examples since it is just EF. In the ADO.NET DAL you must create objects using the factory pattern.

var customerCollection = new CustomerCollection();
var customer = customerCollection.NewItem();
customer.FirstName = "John";
customerCollection.AddItem(customer);

You can select and edit the object like so.

var customer = CustomerCollection.SelectByPK(1);
customer.FirstName= "Bob" ;
customer.Persist();

You can save a whole collection by calling the Persist on the collection object as well.

You can delete a single record by calling the Delete method (assuming it has no child dependencies in the database).

I guess I do not understand what errors you are getting. Please post some code so I can see what you are doing. What error are you getting? When ask ask about getting an item in the constructor, what object are you talking about? Please post more information.

Mar 11, 2011 at 8:20 AM
Edited Mar 11, 2011 at 10:58 AM

I'm sorry about the little information, I'll set that right.

The constructor is this:

 

public FormClient(Client client)
        {
            InitializeComponent();

            // map the client attributes with the textboxes
            // code ommited to make it shorter
            
            // currentClient is a private variable that is available in the whole form
            currentClient = client;
            
            toolStripButtonDelete.Enabled = true;
        }

private void toolStripButtonDelete_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("Are you sure you want to delete this client?",
                "Delete " + textBoxName.Text.ToString(), MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                currentClient.Delete();
                currentClient.Persist();
            }
        }

 

The error is:  This row has been removed from a table and does not have any data.  BeginEdit() will allow creation of new data in this row.

The client I hand to the constructor is a valid client, gotten with the code: Client c = Client.SelectUsingPK(11);

EDIT: Why is it that if I use the clone function of an object (i.e.

Client client = (Client)currentClient.Clone(currentClient.ClientID);
), the IsParented parameter is set to false, while the ParentCollection is copied? Thus preventing me of using client.Persist();

Coordinator
Mar 11, 2011 at 9:30 PM

If you use the Clone method, the resulting object is a detached copy of the original. Persist will have no effect. Just use the "real" object. As long as you do not call Persist no changes will be saved to the database. So your user can change anything he wishes, but no permanent database changes will be made until you the programmer call "Persist".

Also you cannot delete an object the way you are doing it. When you call Delete on an object the object is removed from the collection and you cannot see it anymore. You will most likely get an error this way. You need to call Persist on the parent collection. Once you call Delete on an entity object you can not interact with it anymore.

currentClient.Delete();
clientCollection.Persist();

Mar 12, 2011 at 12:12 PM

Then I have two questions for you.

1. I get the client as argument from another form, as seen in the constructor FormClient(Client client). Can I add this to a ClientCollection without accessing the database. It would seem redundant if you have a client and then you'd have to retrieve it from the database so you could update or delete it. If I use clientCollection.AddItem(client), it would add the existing client as a new client in the local clientCollection.

2. The reason I'm cloning this client is to see if it is being modified. Yes, I'm aware your objects have an ItemState property that sais this. But I saw that when I do something like

 client.Name = textboxName.Text.ToString();

and the name in the box hasn't changed, the ItemState will be set to Modified, thus triggering an update that isn't needed. If I have an exact clone, I can use something like:

 if (!currentClient.Equals(client)) { ... }

 

In your defence, I'm probably looking at this wrong. Your way would suggest two database actions: one to retrieve the item at the beginning of the form and a write changes to database when I close the form. These two would be independent of the number of updates, deletes or inserts I generate in the form. While my way would suggest a database action each time I click a save or delete button. I'll start experimenting with this while I await for you to tell me how wrong my inexperienced ass is.  :)

Mar 12, 2011 at 8:31 PM

I solved it.

I managed to get it to do it like my "In your defence" part. One database access to load the data and one database access to write all data away. All actions I do in between are stored in the collection. It took some rewriting, but it's a lot better (and more efficient).

Thanks for your help. :)