How do I recover from delete operation...

How do I recover from delete operation...

Old forum URL: forums.lhotka.net/forums/t/2639.aspx


yogeshprabhu posted on Thursday, March 29, 2007

Hello,

I’m new to CSLA based development I'm using CSLA Version 2.1.4.

In my business layer I have created a root object inheriting from Csla.BusinessBase<T> and an editable collection of root by inheriting from Csla.EditableRootListBase<T>.  The root object has standard Data Portal methods to insert, update and delete the data.

In the Windows Forms UI, I have data-bound this list to the DataGridView, similar to the code shown in PTracker sample. I could insert, update, and delete items as expected.  Whenever I pressed Esc key during the updates, I got the expected behavior of changes being undone. I have also created event handler for DataError event of the DataGridView. This is the only place errors are shown to the end-user.

private void domainListDataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)

{

  if (e.Exception != null)

  {

    MessageBox.Show(e.Exception.Message, "Error");

    e.Cancel = true;

  }

}

 

I ran into the problem when SQL stored procedure throws an error for violating check constraints. For example deleting a record that is referenced else where throws an error something like “The DELETE statement conflicted with…”. I wrapped this exception in my business layer with friendlier error message, but I can not figure out how to undo the delete operation after showing the error. Pressing Esc key after this error is shown has no effect. Once this error is shown, I keep on getting the exact same error if I click anywhere else in the grid. So if DataPortal_DeleteSelf fails, how do I change the business object’s internal state?

 

Thanks

 

Yogesh

 

yogeshprabhu replied on Friday, March 30, 2007

In case of deletion exception, I marked the business object to be Clean. This seemed to fix my UI issue, and now I can navigate around, after showing the error once to the end user, but it doesn't seem right. Thoughts, anybody?

private void DataPortal_Delete(Criteria criteria)

{

  Database db = DatabaseFactory.CreateDatabase();

  using (DbCommand cmd = db.GetStoredProcCommand("Code_Delete"))

  {

    db.AddInParameter(cmd, Fields.TableName, DbType.String, criteria.CodeType);

    db.AddInParameter(cmd, Fields.ItemId, DbType.Int16, criteria.Id);

 

    try

    {

      db.ExecuteNonQuery(cmd);

    }

    catch (Exception ex)

    {

      // Because of the database exception, this object won't be deleted. Marking it

      // clean seems to work from the UI standpoint, but is this the right way to

      // recover the bussiness object state?

      MarkClean();

      if (ex.Message.StartsWith("The DELETE statement conflicted"))

        throw new ApplicationException("Related records exist, child record(s) must be deleted first.", ex);

      else

        throw ex;

    }

  }

}

Yogesh

SonOfPirate replied on Friday, March 30, 2007

It seems to me that you are working with a collection of items if you are binding a DataGridView.  So, my thinking is that your problem is at the collection level, not with the object itself.  Yes, you should still mark the object as undeleted (_isDeleted = false), I don't know that I agree with marking it clean as that would indicate that any changes that were made to the record prior to being deleted but not yet persisted had, in fact, been persisted.  I would leave it dirty but indicate that it is not deleted.

Back to my original thought...  The reason that the escape key is not having an affect on your UI is most likely due to the fact that the object was removed from your collection despite failing at the database.  I would look at this code, maybe stepping through it, to see if you are properly moving the item into the deleted items collection when deleted then back into the base collection when the escape key is pressed.  Then I'd look at how you can automatically do this when the delete operation fails.

HTH

 

JoeFallon1 replied on Friday, March 30, 2007

Also - your SP could delete the child records for you based on the ID of the top level record. Then the command would tend to succeed more often. <g>

Joe

 

Copyright (c) Marimer LLC