Often times you find yourself needing to update the values from a web form into a database. This is usually a straightforward process. But what happens if you want to issue updates on only those values that have changed in the web form. And what if you want an easy pattern to use given that the set of values to be updated might grow (or, not likely, reduce) in future. In this example, I offer the case of updating personal information.
Probably you have a form where a user can update his personal information. Whether you are using Windows Forms or web forms (I will use web forms in this example) you are using a bunch of Web Controls to capture the data (drop down lists, text boxes, radio buttons, etc..). And maybe you don't want to update every value in the table that stores this information because there exists some trigger that does something when a value is updated. Or maybe you have a lot of hits and just don't want the transaction log to fill. Or maybe your users are intellectually challenged and often hit the Submit button even when they have not updated anything and you don't want the call to be issued carte blanche. The following solution will attempt to provide a pattern to handle this situation.
Using the code
The methodology is essentially to maintain a Hash table of parameter names/parameter values, taking into account only those values that have changed in the web form. By populating this
System.Web.UI.Page class instance variable that we declare, we can pass this value into some method that is responsible for issuing the call to update the database. This update method will extract these parameter names and values and issue a call to the stored procedure responsible for the update.
The code to do this is as follows:
- Create a
private instance variable of
System.System.Collections.Hashtable. This variable is going to be responsible for associating stored procedure parameter names with the newly created (and guaranteed to be different - more on this later) value from the user.
private System.Collections.Hashtable _changeList;
- Create a
private instance method that populates the table with the key/value parameters just mentioned.
private void Add2Collection(string name, string newValue)
if(null == _changeList)
_changeList = new Hashtable();
- Wire up every Web Control's
ValueChanged event. For instance:
System.Web.UI.WebControls.TextBox = TextChanged
System.Web.UI.WebControls.DropDownList = SelectedIndexChanged
System.Web.UI.WebControls.CheckBox = CheckedChanged
And now the aspx markup should look like:
<asp:TextBox id="txtName" runat="server"
<asp:DropDownList id="cmbAge" runat="server"
Notice that I did not wire up an event for the
rbFemale radio button. This is because they are both members of the same group and I am asserting the table that stores this field is defined as:
CREATE TABLE UserData
So, if the user was male and clicks on
rbFemale, then that will trigger a call to
rbMale_Changed(). If the user was female and clicks on
rbMale, again that will issue a call to
rbMale_Changed(). Hopefully, no one is getting too many sex changes.
- In each of those events, issue a call to
public void txtName_Changed(object sender, EventArgs e)
public void cmbAge_Changed(object sender, EventArgs e)
public void rbMale_Changed(object sender, EventArgs e)
This is how we guarantee that
_changeList will be
null if nothing has changed. Only the calls to
Add2Collection will initialize this variable. And if nothing changes, then this variable will remain
null and flag us that we don't need to make a call to the database.
- Finally, there is the button that issues the call to update:
<asp:Button id="btnUpdate" runat="server"
And the code behind it is:
public void btnUpdate_Click(object sender, System.EventArgs e)
The update method is very simple. It accepts the
_changeList, or in this case a class implementing
IDictionary. These entries are now guaranteed to contain the parameter names and their new values. We extract these pairs using an enumerator to gather the parameter names and parameter values, load them into a
SqlCommand and issue the call. Of course, we just return if
IDictionary object is
private static void Update(IDictionary parameterCollection)
if(null == parameterCollection)
const string sproc = "SomeUpdateSproc";
using(SqlConnection connection =
using(SqlCommand command =
new SqlCommand(sproc, connection))
command.CommandType = CommandType.StoredProcedure;
foreach(DictionaryEntry entry in parameterCollection)
SqlParameter parameter =
command.Parameters.Add("@" + entry.Key, entry.Value);
parameter.Value = entry.Value; }
I made this method
static and accepted the instance variable as a parameter because this will be wrapped in some Data Access Layer code. Just move this out of the code-behind page and put it into the Data Access Layer.
Lastly the stored proc would look like:
CREATE PROCEDURE [dbo].[SomeUpdateSproc]
@userName varchar(50) = null,
@userAge int = null,
@isMale bit = null
if @userName <> null begin
if @userAge <> null begin
if @isMale <> null begin
And that is it. As new fields are added to the table that need to be updated in the same manner, just add the appropriate web control, set its
Changed event handler, issue the
Add2Collection() call and add the appropriate logic to the stored procedure.