Search code examples
asp.netlinq-to-sqlsharepoint-2010datagridlinqdatasource

Refreshing a DataGrid after delete/update


The Setup

I have an application page which I try to deploy to SharePoint 2010. The page contains an SPGridView and a LinqDataSource like this:

<asp:UpdatePanel ID="Update" runat="server" >
    <ContentTemplate>
        <center>
            <asp:LinqDataSource runat="server"                    
                    ID="EntitiesSource" 
                    onSelecting="EntitiesSource_Selecting"                                
                    EnableDelete="true"
                    EnableUpdate="true"
                    EnableInsert="true" />

            <SharePoint:SPGridView runat="server"
                    ID="EntitiesGrid"
                    AutoGenerateColumns="false"
                    DataKeyNames="Key"
                    FilteredDataSourcePropertyName="Where"
                    FilteredDataSourcePropertyFormat='{1} == "{0}"'
                    OnRowDeleting="EntitiesGrid_RowDeleting"
                    OnRowUpdating="EntitiesGrid_RowUpdating"
                    AllowPaging="true"
                    AllowSorting="true"
                    PageSize="20"
                    ShowFooter="true"
                    DataSourceID="EntitiesSource">

                <pagersettings mode="Numeric"
                       position="Bottom"           
                       pagebuttoncount="20"/>

                <pagerstyle backcolor="Control"
                       verticalalign="Bottom"
                       horizontalalign="Center"/>

                <Columns>                            

                    <asp:CommandField HeaderText="Actions" ButtonType="Link" ShowEditButton="true" ShowDeleteButton="true" ShowCancelButton="true"  />
                    <asp:BoundField HeaderText="Key" DataField="Key" SortExpression="Key" />
                    <asp:BoundField HeaderText="Var a" DataField="A" SortExpression="A" />
                    <asp:BoundField HeaderText="Var b" DataField="B" SortExpression="B" />
                    <asp:BoundField HeaderText="Var c" DataField="C" SortExpression="C" />

                </Columns>                                    

            </SharePoint:SPGridView>  
        </center>

    </ContentTemplate>
</asp:UpdatePanel>

The code behind looks like this:

public partial class EntitiesPage: LayoutsPageBase
{
    private MyContext _dbcontext;
    private MyContext DBContext
    {
        get
        {
            if (_dbcontext == null)
            {
                string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["entitiesConnectionString"].ConnectionString;
                _dbcontext = new MyContext(connectionString);
            }

            return _dbcontext;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        EntitiesGrid.PagerTemplate = null;
    }

    protected void EntitiesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {         
        string key = (string)e.Keys[0];
        DBContext.RemoveEntity(key);
        DBContext.SubmitChanges();

        //the entity is gone from the context now             
        EntitiesGrid.DataBind();                      
    }

    protected void EntitiesGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        string key = (string)e.Keys["Key"];
        string newKey = (string)e.NewValues["Key"];

        if (string.Equals(key, newKey))
        {
            Entity entity = DBContext.GetEntity(key);
            entity.A = (string)e.NewValues["A"];
            entity.B = (string)e.NewValues["B"];
            entity.C = (string)e.NewValues["C"];
            DBContext.SubmitChanges();
        }
        else
        {
            //We need to remove the old one and make a new one since we can't edit the key
            DBContext.RemoveEntity(key);
            DBContext.AddEntity(new Entity{ Key = newKey, A = (string)e.NewValues["A"], B = (string)e.NewValues["B"], C = (string)e.NewValues["C"] });
            DBContext.SubmitChanges();
        }
    }

    protected void EntitiesSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {
        e.Result = DBContext.Entities;
    }

The 'MyContext' class is a custom class which inherits DataContext and uses linq2sql. It has a single table of my own entity class.

The Issue

Reading data from the database, sorting and paging works really well and really quickly. My grid changes without the page needing to reload. When I update or delete a row, however, I need to manually refresh before I see the changes that were made to the database. I am sure that the changes I make are immediately carried out towards the DataContext and the database. The missing link here seems to be getting the DataSource or the GridView (or both) to refresh.

Debugging this has been a pain and I can't really tell (or I don't know how to tell) whether the problem is updating the objects of my DataSource/GridView, or whether it's sending a call back to the user after those objects have been updated.


Solution

  • Did you try creating a method that binds the datasource to the grid and call that method after your changes are made?

    // Create a method for binding the data
    public void bindTheGrid()
    {
         EntitiesGrid.Datasource = variables; //This is whatever your properties are etc
         EntitiesGrid.DataBind();
    }
    
    //Call the method after you succesffuly make changes to the database etc
    bindTheGrid();