I will not start another debate whether datasets are good or evil. If you continue to use them, here are something to consider:
- You need to keep the original dataset and update that, in order to get correct inserts and updates.
- You want your parents to know their children, but not the other way. Banish the ParentTable.
- An Order and its OrderDetails is an aggregate (from Domain Driven Design) and should be considered as a whole. A call to order.Save() should save everything.
Well, that's the theory. How can we do that? One way is to create the following artifacts:
- Order
- OrderDetail
- OrderRepository
- OrderMap
The OrderMap is where you manage the Order to Dataset relationships. Internally, it could use a Hashtable or a Dictionary.
The OrderRepository is where you get your Orders from. The repository will get the dataset with all relations from somewhere, build the Order with all its OrderDetails, and store the Order/Dataset relationship in the OrderMap.
The OrderMap must be kept alive as long as the Order is alive.
The Order contains all OrderDetails.
Pass the order to the repository and let it save it. The repository will get the dataset from the map, update the Order-table from the order and iterate all order-details to update the OrderDetail-table.
Retrieve and save:
var order = repository.GetOrder(id);
repository.Save(order);
Inside OrderRepository.GetOrder():
var ds = db.GetOrderAndDetailsBy(id);
var order = new Order();
UpdateOrder(ds, order);
UpdateOrderDetails(ds, order); // creates and updates OrderDetail, add it to order.
map.Register(ds, order);
Inside OrderRepository.Save():
var ds = map.GetDataSetFor(order);
UpdateFromOrder(ds, order);
foreach(var detail in order.Details) UpdateFromDetail(ds.OrderDetail, detail);
Some final notes:
- You can implement the map as a singelton.
- Let the map use weak references. Then any order should be
garbage-collected when it should,
and memory will be freed.
- You need some way to associate an OrderDetail with its table-row
- If you have the slightest possibility to upgrade to .NET 3.5, do it. Linq to Sql or Linq to Entity will remove some of your pain.
- All of this is created out of thin air. I hope it's not too inaccurate.