Practical ASP.NET

Object-Oriented Updates with the ObjectDataSource

If you're going to use the ObjectDataSource in a real application, you'll need to support all of the CRUD activities. Peter Vogel extends his object model to do just that.

In previous columns (Supporting the ObjectDataSource and Object Oriented Development for the ASP.NET Developer) I walked through a simple model for developers wanting to move from single-tier development to multi-tier development. In an earlier column (In Defense of Single-Tier Applications), I also covered why you might need to make the move. To date, however, all I've covered is how to get data out of your tables and onto your page. To fully support the ObjectDataSource in any real world application, you'll need to support updates, deletes and inserts.

The ObjectDataSource assumes that you're going to implement the Factory Method pattern (as I described in "Supporting the ObjectDataSource"), which uses two classes for every business entity: a factory class that handles creating objects from database tables and a data class that carries the data to the page. The code to handle updates goes in methods in the factory object, because updates are just the reverse of the existing methods in the factory. Instead of converting rows into objects, these new methods convert objects into rows.

Implementing Updates
The ObjectDataSource expects you to have one method for each of the insert, delete and update operations. The ObjectDataSource will pass these methods an object that the factory produces, depending on what the user has done in your application's pages. For instance, if the user deletes a row in a GridView of Customers, then the ObjectDataSource will pass a Customer object representing that row to a method on your factory. It's your responsibility in that method to do whatever is necessary to delete the corresponding row in the database.

I selected the delete method because it's the easiest to implement. Here's a typical delete method that accepts the Customer object I used in previous columns:

Share Function DeleteCustomer(Cust As Customer)
Dim rdr As SqlDataReader
Dim con As New SqlConnection(...connection string...)
Dim cmd As SqlCommand = con.CreateCommand()
cmd.CommandText = "Delete from Customers " & _
" Where CustomerId = @CustId"
cmd.Parameters.AddWithValue("CustId", Cust.Id)

Dim intRecordsAffected As Integer
con.Open()
intRecordsAffected = cmd.ExecuteNonQuery
con.Close

Return intRecordsAffected

End Function

The update and insert methods are almost identical to this method, except for changes in the SQL statement and the addition of more parameters.

Handling Concurrency
However, you may want to consider concurrency issues (two users accessing the same record at the same time). For inserts, concurrency simply isn't a problem. Because the record doesn't exist until the user adds it, no other user can be working with a record that is about to be inserted.

My attitude is the same towards deletes: If one user deletes a record that another user is either trying to delete or update... well, life's just like that. But if that's too laissez-faire for you, then there are two scenarios you need to consider when deleting a record: (a) some other user is updating the record on another page but has not yet saved it, or (b) a user updated and saved a record on another page in the time between when the current user retrieved a record and has gotten around to deleting it.

First, I'm assuming that you're not going to lock records when retrieving them. That means there's nothing you can do about the first scenario: When the user doing updates finally saves the change, the record they've been updating will be gone. In your update code, the ExecuteNonQuery that executes the update will return 0 and the page developer can decide what to do with that information in the ObjectDataSource's RowUpdated event. (For more, see this column.)

I've discussed second scenario in other columns, also. My personal solution is to just delete the record based on the "He who updates last, updates best" rule. If you'd prefer to show the user the updated record and make them confirm the delete ,then see my previous column on handling optimistic concurrency in the ObjectDataSource. Fundamentally, the solution suggests that you build a Where clause that checks that no values have changed since the row was retrieved and skip deleting the record when any values have changed.

As I discuss in that column, for updates I do recommend one extension to the simple method I've discussed here. Only update those fields where the user has made a change (also discussed in my previous column). Most concurrency issues disappear if you avoid updating every field in a database row because the user changed one field.

In an earlier column, I pointed out that it's unlikely that your business objects will match the layout of your pages, and I provided a simple solution to that problem. In my next column, I'm going to return to that problem to provide a more sophisticated (and extensible) solution

.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events