VS2010 RC - Azure table create, read, update and delete (CRUD) / ObjectDataSource delete bug

There seem to be plenty of examples for working with Azure blobs (which is great because it is my next step) but I found information on tables to be lacking.   Particularly CRUD operations outside of read and write.  

Once I had the fundamentals down I found there were a number of mistakes one could make that would result in a ResourceNotFound error.    My goal is to abstract the complexities away into base classes and keep it simple in the parent classes - important because the Electronic Health Record system will have numerous tables (based on Microsoft HealthVault classes - highly normalized).

The following is the minimal code required to get an application running with an ObjectDataSource (using GWN.Contrib.Azure project) - all code and default.aspx form below:

The base classes actually handle all of the wire-up and plumbing however the ObjectDataSource requires strongly typed objects (not generics) to bind to so I had to provide wrapper methods in my PersonDataSource above (lines 11-22).   If you are not using an ObjectDataSource no lines of code are required.

Default.aspx and code-behind  ---  everything is handled by the ObjectDataSources


Once I dropped a ListBox and DetailsView on my .ASPX page I clicked on the data binding tab of each control (shown on the top right hand corner of the ListBox above) and created two ObjectDataSources with both of them bound to the same PersonDataSource.   The odsList binds to the Read() method (in the baseclass) and the odsDetails binds to the CreateItem, ReadItem, UpdateItem and DeleteItem methods shown in the first image above. Attempting to bind to the generic baseclass methods generated errors noting this was not permittted so I created the wrapper methods and all was well.  

Note:  When creating the ObjectDataSources using the wizard VS2010 RC doesn't like to show all of the available classes the first time you select the dropdown list.  I had to show the list, close everything back to the control and then restart the process; VS will then consistently show all classes permitting you to access the PersonDataSource which resides in a separate project (below) - feature or bug???

ObjectDataSource DELETE BUG:   **UPDATED**
Unlike it's Insert and Update counterparts the Delete method would consistently send the PersonDataSource DeleteItem method an empty item (line 20 in the first image).  It had been a while since worked with ObjectDataSources so I figured maybe I was missing something but after a few hours of research and trying different things came to the conclusion it was a bug.  

My work-around was to tap into the odsDetails_Deleting method and manually instantiate the PersonDataSource, grab the selected value and call the DeleteItem() method on it.    This results in the PersonDataSource being called twice with the second results (empty value) being ignored by the base classes.

Posted by Microsoft on 2/23/2010 at 1:19 PM
The behavior you are seeing is actually the way that data controls in ASP.NET work. Our controls basically build an object from the controls that are on the page. In the case of an update there are controls on the page (TextBox, CheckBox, etc) that when the page is posted back retain their state. We take the values of these and build a new object from that state. In the case of a delete operation since there are no controls that retain state between pages we do not have the data necessary to reconstruct the object.

You can run into a similar problem with update operations if you only have controls for SOME of the properties. The properties for which you do not have controls will not have their state retained.

To work around this there is a DataKeys property on the data control. You can specify a list of all the columns that you would like persisted by specifying them in this property. We keep this state all the time so it allows you to control how much state you want us to keep between postbacks.

Head Banger

The following method in my DataContextBase (GWN.Contrib.Azure) was the source of hours of lost work.  Instead of doing the following I created an IQuerable<TItem> List<TItem>() method in the base classes to handle its functionality - this worked great and the coding went on.   When I was done I reset the development storage, which effectively wiped out all of the existing data, and my application would not recreate the table (ResourceNotFound error)!!! 

public IQueryable<TItem> List
{
   get
   {
        // The string name must match property name
       
return this.CreateQuery<TItem>("List");
   }
}

Moral to the story was that the above property is important to the CreateTablesFromModel method (in the DataSourceBase static constructor).

Note: currently the base classes blow by errors (won't crash the application).  I have TODO: statements where I will be logging the errors to Azure since preliminary research indicates this is the only way our application can communicate issues to us.   Work in progress - I have Blobs to work on!!

 


Tags: , ,
Categories: Azure


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know