Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Using optimistic concurrency when editing data in gridview - Part 19

Suggested Videos 
Part 16 - ConflictDetection property of objectdatasource control
Part 17 - Editing and updating data in gridview using sqldatasource control
Part 18 - Editing and updating data in gridview using objectdatasource control



In Part 18 of the asp.net gridview tutorial we discussed the basics of editing and updating data in gridview control. We did not discuss about concurrency in Part 18. Let me explain what I mean.
1. When you access the webform, data is loaded into gridview control.
2. Now click on Edit, while you are still editing data, someone else has updated the same row in the underlying database table
3. Now, in the gridview, when you click UPDATE button on the row that has changed, the row gets overwritten with your new data. This may or may not be a problem, depending on the requirements of your application. But if your project requirement warrants that, the data should not be overwritten, if it has changed since it was loaded into gridview control, then we need to think about implementing optimistic concurrency.



We will be modifying the "UpdateEmployee()" method in EmployeeDataAccessLayer.cs file. We discussed about this in Part 18. Please change the implementation of UpdateEmployee() method as shown below. Notice that, along with the new values, the ORIGINAL EmployeeId, Name, Gender and City are also passed as parameters to the UpdateEmployee() method. These parameters are then used in the "UPDATE" query, to check if the data has changed after it was loaded into the gridview control.
public static void UpdateEmployee(int original_EmployeeId, string original_Name, string original_Gender, string original_City, string Name, string Gender, string City)
{
    string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
    using (SqlConnection con = new SqlConnection(CS))
    {
        string updateQuery = "Update tblEmployee SET Name = @Name,  " +
            "Gender = @Gender, City = @City WHERE EmployeeId = @original_EmployeeId " +
            "AND Name = @original_Name AND Gender = @original_Gender AND City = @original_City";
        SqlCommand cmd = new SqlCommand(updateQuery, con);
        SqlParameter paramOriginalEmployeeId = new SqlParameter("@original_EmployeeId", original_EmployeeId);
        cmd.Parameters.Add(paramOriginalEmployeeId);
        SqlParameter paramOriginalName = new SqlParameter("@original_Name", original_Name);
        cmd.Parameters.Add(paramOriginalName);
        SqlParameter paramOriginalGender = new SqlParameter("@original_Gender", original_Gender);
        cmd.Parameters.Add(paramOriginalGender);
        SqlParameter paramOriginalCity = new SqlParameter("@original_City", original_City);
        cmd.Parameters.Add(paramOriginalCity);
        SqlParameter paramName = new SqlParameter("@Name", Name);
        cmd.Parameters.Add(paramName);
        SqlParameter paramGender = new SqlParameter("@Gender", Gender);
        cmd.Parameters.Add(paramGender);
        SqlParameter paramCity = new SqlParameter("@City", City);
        cmd.Parameters.Add(paramCity);
        con.Open();
        cmd.ExecuteNonQuery();
    }
}

Compile the project and re-configure ObjectDataSource1 control, to use the above method as it's UPDATE method.

On "ObjectDataSource1" control, set properties
ConflictDetection = "CompareAllValues"
OldValuesParameterFormatString = "original_{0}"

Setting ConflictDetection="CompareAllValues", will pass original values for EmployeeId, Name, Gender and City to UpdateEmployee() method. 

Notice the parameters of the UpdateEmployee() method. Some of them have a prefix of "original_". ObjectDataSource control uses "OldValuesParameterFormatString" property to figure out the exact name of the parameters for the original values. This is the reason we have set OldValuesParameterFormatString="original_{0}"
public static void UpdateEmployee(int original_EmployeeId, string original_Name, 
string original_Gender, string original_City, string Name, string Gender, string City)

To make EmployeeId Non-Editable, set ReadOnly="true", on EmployeeId bound column
<asp:BoundField DataField="EmployeeId" HeaderText="EmployeeId" 
    SortExpression="EmployeeId" ReadOnly="true" />

Finally, on "GridView1" set DataKeyNames="EmployeeId"

With all the above changes, the declarative HTML markup of gridview and objectdatasource control, should be as shown below.
<div style="font-family:Arial">
    <asp:GridView ID="GridView1" runat="server" 
    AutoGenerateColumns="False" BackColor="#DEBA84" 
    BorderColor="#DEBA84" BorderStyle="None" 
    BorderWidth="1px" CellPadding="3" CellSpacing="2" 
    DataSourceID="ObjectDataSource1" DataKeyNames="EmployeeId">
        <Columns>
            <asp:CommandField ShowEditButton="True" />
            <asp:BoundField DataField="EmployeeId" HeaderText="EmployeeId" 
                SortExpression="EmployeeId" ReadOnly="true" />
            <asp:BoundField DataField="Name" HeaderText="Name" 
                SortExpression="Name" />
            <asp:BoundField DataField="Gender" HeaderText="Gender" 
                SortExpression="Gender" />
            <asp:BoundField DataField="City" HeaderText="City" 
                SortExpression="City" />
        </Columns>
        <FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
        <HeaderStyle BackColor="#A55129" Font-Bold="True" 
            ForeColor="White" />
        <PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
        <RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
        <SelectedRowStyle BackColor="#738A9C" Font-Bold="True" 
            ForeColor="White" />
        <SortedAscendingCellStyle BackColor="#FFF1D4" />
        <SortedAscendingHeaderStyle BackColor="#B95C30" />
        <SortedDescendingCellStyle BackColor="#F1E5CE" />
        <SortedDescendingHeaderStyle BackColor="#93451F" />
    </asp:GridView>
    <br />
    <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
        SelectMethod="GetAllEmployees" TypeName="Demo.EmployeeDataAccessLayer" 
        UpdateMethod="UpdateEmployee" 
        OldValuesParameterFormatString="original_{0}" 
        ConflictDetection="CompareAllValues">
        <UpdateParameters>
            <asp:Parameter Name="original_EmployeeId" Type="Int32" />
            <asp:Parameter Name="original_Name" Type="String" />
            <asp:Parameter Name="original_Gender" Type="String" />
            <asp:Parameter Name="original_City" Type="String" />
            <asp:Parameter Name="Name" Type="String" />
            <asp:Parameter Name="Gender" Type="String" />
            <asp:Parameter Name="City" Type="String" />
        </UpdateParameters>
    </asp:ObjectDataSource>
</div>

1 comment:

  1. Sir,
    Setting setting both Readonly property true and Datakeynames, getting an
    run time error please check it and make a note of it....

    ReplyDelete

It would be great if you can help share these free resources