Help with timestamps in ObjectContainerDataSource

Topics: Web Client Software Factory
Oct 18, 2007 at 2:50 AM
Hi all,
I have a quick question regarding the use of timestamps with the ObjectContainerDataSource. I have table "Company" which has, amongst other columns, a timestamp column. This table is the source for a business object. I am trying to use the ObjectContainerDataSource to display certain fields in this object for editing. I don't want to include the timestamp column in the fields displayed by the GridView that uses this ObjectContainerDataSource. The problem I am having is that when the ObjectContainerDataSource fires off its updating event, all values for that object not included in the GridView are being set to null and I am losing the timestamp value (as well as all of the other properties in the Company object not included in the GridView). I have tried including the timestamp in a BoundField in the gridview marked as not visible and it has not helped.

Does anyone have any ideas on how I can retain the timestamp (and other existing values) on an object used in this scenario?

Oct 18, 2007 at 6:14 AM
Indeed, that is the behavior I've seen as well. And I'm not sure how a DataSourceControl is supposed to behave in general. But the way I've worked around this, is that I try to find the original item (using the object's functional key) from within the presenter and then selectively copy the modified properties from the new object to the original one. The thing is, you can only do that if you know which properties might have been changed through the view. An alternative, but similar, approach is to do this in the Updating event handler of the view itself. You simply iterate over the items in the ObjectContainerDataSource and do the same.
Oct 18, 2007 at 8:46 AM
Try adding your timestamp property name after the primary key property name in the DataKeyNames property of the GridView
Oct 18, 2007 at 1:29 PM
dennisdoomen - would you mind posting an example of how you have done this from within the presenter? Thanks!
Dec 12, 2007 at 6:42 PM

A possible solution could be changing the ExecuteUpdate method in ObjectContainerDataSourceView class from WebControls project (SC-SF source code). (see New Code to populate old values region)

protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues)
   Guard.CollectionNotNullNorEmpty(keys, String.Format(CultureInfo.CurrentCulture,  Properties.Resources.NoKeysSpecified), "keys");
   Guard.ArgumentNotNull(values, "values");
   ObjectContainerDataSourceUpdatingEventArgs updatingEventArgs = new ObjectContainerDataSourceUpdatingEventArgs(DictionaryHelper.GetReadOnlyDictionary(keys), values, oldValues);
   if (updatingEventArgs.Cancel)
      return 0;
   object newInstance = CreateInstance();
   TypeDescriptionHelper.BuildInstance(keys, newInstance);
   TypeDescriptionHelper.BuildInstance(values, newInstance);
   int rowsAffected;
   object oldInstance = FindInstance(keys);
   if (oldInstance != null)
      #region New Code to populate old values
      PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(oldInstance);
      foreach (PropertyDescriptor property in properties)
         if (!keys.Contains(property.Name) && !values.Contains(property.Name))
            property.SetValue(newInstance, property.GetValue(oldInstance));
      int index = Data.IndexOf(oldInstance);
      Data[index] = newInstance;
      rowsAffected = 1;
      rowsAffected = 0;
   ObjectContainerDataSourceStatusEventArgs updatedEventArgs = new ObjectContainerDataSourceStatusEventArgs(newInstance, rowsAffected);
   return rowsAffected;

Note: This solution not work in the case you have read-only properties in your data object.

For this and other possible solutions, I recommend that you read this thread


Sebastian Iacomuzzi