locked
synchronizing deletes to database RRS feed

  • Question

  • I have a question about the best way to have an application remember that objects that correspond to database rows were deleted, and then persist those changes to the database once the "save" method is called.  I'm developing the business layer and data access layer for my application.  My business objects are as follows:

    class Contract
    {
    	private bool IsDirty { get; set; }
    
    	public string ContractId
    	{
    		get
    		{
    			return _contractId;
    		}
    		set
    		{
    			if (_contractId != value)
    			{
    				_contractId = value;
    				IsDirty = true;
    			}
    		}
    	}
    	private string _contractId;
    
    	public string Description
    	{
    		get
    		{
    			return _description;
    		}
    		set
    		{
    			if (_description != value)
    			{
    				_description = value;
    				IsDirty = true;
    			}
    		}
    	}
    	private string _description;
    <br/>    // This is where I'm having my problem
    	public List<Item> Items
    	{
    		get
    		{
    			return _items;
    		}
    	}
    	private List<Item> _items = new List<Item>();<br/><br/>    public void Save()<br/>    {<br/>       // Call data access layer and perform database updates here<br/>    }<br/> }
    
    class Item
    {
    	private bool IsDirty { get; set; }
    
    	public string Description
    	{
    		get
    		{
    			return _description;
    		}
    		set
    		{
    			if (_description != value)
    			{
    				_description = value;
    				IsDirty = true;
    			}
    		}
    	}
    	private string _description;
    
    	public string ItemId
    	{
    		get
    		{
    			return _itemId;
    		}
    		set
    		{
    			if (_itemId != value)
    			{
    				_itemId = value;
    				IsDirty = true;
    			}
    		}
    	}
    	private string _itemId;
    
    	public string ItemGroup
    	{
    		get
    		{
    			return _itemGroup;
    		}
    		set
    		{
    			if (_itemGroup != value)
    			{
    				_itemGroup = value;
    				IsDirty = true;
    			}
    		}
    	}
    	private string _itemGroup;
    }
    

    I would like to be able to remove items from the Items property of a Contract object (i.e. myContractObject.Items.RemoveAt(1)), then have those deletes carry through to the database when I call the Save method of my Contract object.  The actual SQL statements will be done in the data access layer.

    I don't want to add an IsDeleted flag to each Item object and leave them in the Contract.Items property, because then the Contract.Items property will return objects that have been deleted and are not actually part of the Items property anymore.

    I've been considering changing the Contract.Items property from a List<Item> type to a custom type that acts as a List object but also maintains a list of any objects that were removed from the list so that those deletes could be done when the parent Contract object is saved. Something similar to this:

    class ItemList
    {
    	public Item this[int i]
    	{
    		get
    		{
    			return _items[i];
    		}
    	}
    	private List<Item> _items = new List<Item>();
    
    	private List<Item> _deletedItems = new List<Item>();
    
    	public void Add(Item item)
    	{
    		_items.Add(item);
    	}
    
    	public void RemoveAt(int i)
    	{
    		Item item = _items[i];
    		_items.RemoveAt(i);
    		_deletedItems.Add(item);
    	}
    }
    

    I'm convinced that there has to be a better way to do this.  Does anyone have any suggestions?

    Thursday, June 2, 2011 8:18 PM

All replies

  • If you did add an isDeleted flag.

    You could perhaps then use LINQ to objects to return the list filtered for those not deleted.

    Thursday, June 2, 2011 8:23 PM
  • Hi

    I can think of 2 options

    1> Have a clone (deep copy) of entity , when it's loaded (better place to hold is in entity itself in base class), so you will have to compare with original when the entity is dirty. This case you can easily get all deleted sub property list item.

    one more advantage of this is, for validations you dont need to hit DB to get original value. 

    2> based on relationship between Contract and Item, i assume Item must have Contract reference right?

    Instead of having one more property like IsDeleted , Check on nullability of property Contract in Item. For this you have to make sure on remove of Item, setting null to Item's Contract property.


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".
    Friday, June 3, 2011 2:04 AM
  • I would make two lists. A Current List and a Temp List.

    Anything deleted, goes to the Temp List and is removed from the Current List.

    Same thing with any edits or adds. When displaying the items, I display from current, and if the temp list not empty, I know to enable a Save Changes button, and I know the object "isdirty".

    Then I could have an action flag that is set when I add, delete or edit.

    On save, I check the temp list and action flag. If the flag is set to 'deleted', everything in the temp list is deleted.

    If the flag is set to edited, I update the temp list objects in the database. Ditto with anything new.


    Louis
    Tuesday, June 7, 2011 8:11 PM
  • I think if you were maintaining multiple lists then you should be considering just using a dataset instead.

     

    Wednesday, June 8, 2011 9:27 AM