Q:

How to track changes to business objects?

I get the concept of creating a business object or entity to represent something like a Person. I can then serialize the Person using a DTO and send it down to the client. If the client changes the object, it can have an IsDirty flag on there so when it gets sent back to the server I know to update it.
But what if I have an Order object? This has the main header informaton, customer, supplier, required date, etc. Then it has OrderItems which is a List< OrderItem>, being the items to be ordered. I want to be able to use this business object on my UI. So I have some textboxes hooked up  to the location, supplier, required date, etc and a grid hooked up to OrderItems. Since OrderItems is a List I can easily add and delete records to it. But how do I track this, especially the deleted items. I don't want the deleted items to be visible in my grid and I shouldn't be able to iterate over them if I used foreach, because they have been deleted. But I still need to track the fact there was a deletion. How do I track the changes. I think I need to use a unit of work? But then the code seems to become quite complex. So then I wonder why not simply use DataTables and get the change tracking for free? But then I read how business objects are the way to go.
I’ve found various examples on simple Person examples, bnut not header-detail examples like Orders.
BTW using C# 3.5 for this.

A:

Firstly, you can use an existing framework that addresses these issues, like CSLA.NET.  The author of this framework has tackled these very issues. Go to http://www.rockfordlhotka.net/cslanet/ for this.  Even if you don't use the full framework, the concepts are still applicable.
If you wanted to roll your own, what I've done in the past was to instead of using List for my collections, I've used a custom type derived from BindingList.  Inhereting from BindingList allows you to override the behaviour of add/remove item.  So you can for example have another internal collection of "delteted" items.  Every time the overriden Remove method is called on your collection, put the item into the "deleted" collection, and then call the base implementation of the Remove method.  You can do the same for added items or changed items.

