2017-11-17 1 views
-1

you can see VT_AClReport Table design In der folgenden HTML-Markup habe ich eine einfache ASP.Net GridView mit 3 Spalten.Bulk Edit Aktualisieren mehrerer Zeilen in ASP.Net GridView mit CheckBoxes

Die erste Spalte enthält die CheckBox, die zweite Spalte enthält eine Bezeichnung für die Anzeige-ID und den Zugriffspfad des Ordners bzw. die dritte Spalte enthält ein Label und DropDownList für die Anzeige und Bearbeitung des Ordners.

Hier verwende ich GridView mit Paging, um die Daten anzuzeigen, und die Daten sind über Millionen von Zeilen. Wenn ich auf die Schaltfläche "Senden" klicke, um das Kontrollkästchen für die ausgewählten Zeilen zu aktualisieren, benötigt die Ausführungszeit zu viel, um die Zeilen in der Tabelle zu aktualisieren.

Zum Beispiel: für 5000 Zeilen = 26 min. Kann mir jemand helfen, dieses Problem zu lösen und die Ausführungszeit zu reduzieren, um alle Datensätze innerhalb weniger Sekunden zu aktualisieren.

Bitte beachten Sie den Code:

 <asp:GridView ID="gvACLReport" runat="server" AutoGenerateColumns="False"CssClass="mgrid" EmptyDataText="No Records Exists..." DataKeyNames="ACLId" ShowFooter="True" HorizontalAlign="Center" Width="100%" AllowPaging="True" EnableSortingAndPagingCallback="True" PageSize="500" AllowSorting="True" Visible="False" onpageindexchanging="gvACLReport_PageIndexChanging"          EnableSortingAndPagingCallbacks="True"> 
      <AlternatingRowStyle CssClass="mgridalt" /> 
      <PagerSettings PageButtonCount="10000" /> 
      <PagerStyle CssClass="gridview" HorizontalAlign="Center"></PagerStyle> 
      <Columns> 
       <asp:TemplateField> 
        <HeaderTemplate> 
         <asp:CheckBox ID="chkAllACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" /> 
        </HeaderTemplate> 
        <ItemTemplate> 
         <asp:CheckBox ID="chkACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged"/> 
        </ItemTemplate> 
        <ItemStyle Width="20px" /> 
       </asp:TemplateField> 

       <asp:TemplateField HeaderText="ACL Id"> 
        <ItemTemplate> 
         <asp:Label ID="lblACLId" runat="server" Text='<%# Eval("ACLId") %>'></asp:Label> 
        </ItemTemplate> 
        <ItemStyle Width="20px" /> 
       </asp:TemplateField> 

       <asp:TemplateField HeaderText="Access Path"> 
        <ItemTemplate> 
         <asp:TextBox ID="lblAccessPathACL" runat="server" Rows="3" Width="400px" Text='<%# Eval("AccessPath") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox> 
        </ItemTemplate> 
        <ItemStyle Width="150px" /> 
       </asp:TemplateField> 

       <asp:TemplateField HeaderText="Directory Name"> 
        <ItemTemplate> 
         <asp:TextBox ID="lblDirectoryName" runat="server" Rows="3" Width="400px" Text='<%# Eval("DirectoryName") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox>        
        </ItemTemplate> 
        <ItemStyle Width="150px" /> 
       </asp:TemplateField> 


         <asp:TemplateField HeaderText="User Group"> 
                  <ItemTemplate> 
                   <asp:Label ID="lblUserGroup" runat="server" Text='<%# Eval("UserGroup") %>'></asp:Label>        
                  </ItemTemplate> 
                  <ItemStyle Width="150px" /> 
                 </asp:TemplateField> 
      </Columns> 
      <HeaderStyle CssClass="mgridheader" /> 
      <RowStyle CssClass="mgriditem" /> 
     </asp:GridView> 

//Please check this the table contain the drop down list to update the status and submit and clear button 
     <table id ="tableChangeStatus" align="center" width="100%" 
     class="body style1" cellspacing="4" style="border-color: #808080; 
     border-style: solid; border-width: 1px; table-layout: auto;" 
     runat="server" visible="False"> 

       <tr runat="server"> 
         <td align="left" runat="server"> 
           Status: 
         </td> 
         <td runat="server"> 
                <asp:DropDownList ID="ddlChangeStatus" AutoPostBack="True" AppendDataBoundItems="True" 
                 runat="server" Width="200px" DataSourceID="SDSChangeStatus" DataTextField="Status" 
                 DataValueField="StatusId"> 
                 <asp:ListItem Text="--Select--" Value="0"></asp:ListItem> 
                </asp:DropDownList> 
                <asp:SqlDataSource ID="SDSChangeStatus" runat="server" ConnectionString="<%$ ConnectionStrings:gtsgeneralconn %>" 
                 SelectCommand="VT_getStatusList" SelectCommandType="StoredProcedure"></asp:SqlDataSource> 
                <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="ddlChangeStatus" 
                 Display="Dynamic" ErrorMessage="Select Status" InitialValue="0" SetFocusOnError="True">*</asp:RequiredFieldValidator> 
               </td> 
              </tr> 
              <tr runat="server"> 
               <td align="center" colspan="2" runat="server"> 
                <asp:Button ID="btnChangeStatus" runat="server" Text="Submit" CausesValidation="False" 
                 onclick="btnChangeStatus_Click" 
                /> 
                <asp:Button ID="btnChangeClear" runat="server" Text="Clear" 
                 CausesValidation="False" onclick="btnChangeClear_Click" 
                /> 
               </td> 
              </tr> 
              </table> 

-Code Behind:

  protected void ChangeStatusGlobalSensitiveNonSensitiveReport() 
     { 
      int rowsAffected = 0; 
      foreach (GridViewRow row in gvGlobalSensitive.Rows) 
      { 
       if (row.RowType == DataControlRowType.DataRow) 
       { 
        bool isChecked = row.Cells[0].Controls.OfType<CheckBox().FirstOrDefault().Checked; 
        if (isChecked) 
        { 
          using (SqlConnection con = new SqlConnection(cs)) 
          { 
            cmd = new SqlCommand("VT_ACLReportChangeStatus", con); 
            cmd.CommandType = System.Data.CommandType.StoredProcedure; 
            cmd.CommandTimeout = 3600; 
            cmd.Parameters.AddWithValue("@ChangeStatus", ddlChangeStatus.SelectedItem.Text.ToString()); 
            cmd.Parameters.AddWithValue("@ACLId", row.Cells[1].Controls.OfType<Label>().FirstOrDefault().Text); 
            con.Open(); 
            cmd.ExecuteNonQuery(); 
            con.Close(); 
            rowsAffected++; 
          } 
         } 
        } 
        lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!"; 
        lblUpdateMsg.Text = "Detail Saved Successfully!!";    
        gvGlobalSensitive.Visible = false; 
        tableChangeStatus.Visible = false; 
        divReport.Visible = false; 
       } 
       if (rowsAffected == 0) 
       { 
        lblUpdateMsg.Text = "Please select the check box to update the status!!"; 
        lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!"; 
       } 
      } 

Stored Procedure

ALTER PROCEDURE [dbo].[VT_ACLReportChangeStatus] 
    (
     @ChangeStatus nvarchar(50)=null, 
     @ACLId int 
     ) 
    AS 
    // Exec VT_ACLReportChangeStatus 'Complete',34 
    BEGIN 
    UPDATE VT_ACLReport SET Status = @ChangeStatus WHERE ACLId = @ACLId  
    End 
+0

Könnten Sie auch Vorgehensweise Post gespeichert? Können Sie versuchen, nur eine Verbindung zu benutzen? if (row.RowType == DataControlRowType.DataRow) wird nicht benötigt. – Emanuele

+0

Ja, ich habe Stored Procedure hochgeladen Sie können @Emanuele überprüfen – AkshayPorwal

+0

Sie erwähnten irgendwo über das Einreichen der Seite, also wo ist der Submit-Button dafür? – Sunil

Antwort

0

Ersetzen Sie die UPDATE-Anweisung in der gespeicherten Prozedur mit T-SQL unten.

Ich nehme an, ACLId ist der Primärschlüssel mit einem gruppierten Index und Sie haben einen Index auf Status Spalte. Sie wären besser dran, wenn Sie einen anderen Index für ACLId erstellen und die Spalte Status darin einfügen, da dies die Suche in der UPDATE-Anweisung wirklich beschleunigt.

In diesem T-SQL werden Aktualisierungen in Stapeln von 1000 Datensätzen durchgeführt, anstatt den gesamten Datensatz zu aktualisieren. Sie können mit dem Ändern des Wertes von 100 auf etwas wie 500 oder noch weniger herumspielen, um den besten Update-Stapel zu erstellen.

DECLARE @numberOfRowsUpdated INT = 1000, @maxRowsToUpdate INT = 1000; 

BEGIN TRY  
    BEGIN TRAN 

    WHILE (@numberOfRowsUpdated > 0) 
    BEGIN 

    UPDATE TOP (@maxRowsToUpdate) VT_ACLReport SET Status = @ChangeStatus 
      WHERE ACLId = @ACLId and Status <> @ChangeStatus; 

     SET @numberOfRowsUpdated = @@ROWCOUNT; 
    END 

    if @@trancount > 0 
     COMMIT TRAN 

END TRY 
BEGIN CATCH 
    if @@trancount > 0 
     ROLLBACK TRAN 

    -- log and raise error 
END CATCH 
+0

Danke @sunil, ich habe versucht, mit der oben genannten T-SQL-Abfrage, aber es dauert die gleiche Ausführungszeit. Kein Unterschied..Aktuell habe ich mit Checkbox ausgewählt oder nicht, wenn ausgewählt, wird die einzige Abfrage ausgeführt .. Somit wird für jede Zeile eine Abfrage ausgeführt, die die Ausführungszeit erhöht. – AkshayPorwal

+0

Ok. So könnten dieselben Zeilen aus verschiedenen Rasteransichtszeilen aktualisiert werden? – Sunil

+0

Also für jede Zeile dauert es etwa 26 Minuten? – Sunil

0
I solved this problem by maintaining View State, Preserving all checked checkbox state and storing in view state. 

then concatenating all the id's in one variable. 

    protected void gvACLReport_PageIndexChanging(object sender, GridViewPageEventArgs e) 
    { 
     GridView gv = (GridView)sender; 
     PaginateTheData(gv); 
     gvACLReport.PageIndex = e.NewPageIndex; 
     UpdateACLReport(); 
    } 
protected void PaginateTheData(GridView gvAll) 
    { 
     List<int> list = new List<int>(); 
     if (ViewState["SelectedRecords"] != null) 
     { 
      list = (List<int>)ViewState["SelectedRecords"]; 
     } 
     foreach (GridViewRow row in gvAll.Rows) 
     { 
      CheckBox chk = (CheckBox)row.FindControl("chkReport"); 

      var selectedKey = int.Parse(gvAll.DataKeys[row.RowIndex].Value.ToString()); 

      if (chk.Checked) 
      { 

       if (!list.Contains(selectedKey)) 
       { 

        list.Add(selectedKey); 
       } 
      } 

      else 
      { 
       if (list.Contains(selectedKey)) 
       { 

        list.Remove(selectedKey); 
       } 
      } 
     } 

     ViewState["SelectedRecords"] = list; 

    } 

} 

    protected void ChangeStatusACLReport() 
     { 
      int rowsAffected = 0; 
      List<int> list = ViewState["SelectedRecords"] as List<int>; 
      string ACLId = ""; 
      if (list != null) 
      { 
       foreach (int id in list) 
       { 
        ACLId = ACLId + id.ToString() + ","; 
        rowsAffected++; 
       } 
      } 
      else 
      { 
       foreach (GridViewRow row in gvACLReport.Rows) 
       { 
        if (row.RowType == DataControlRowType.DataRow) 
        { 
         bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked; 
         if (isChecked) 
         { 
          ACLId = ACLId + row.Cells[1].Controls.OfType<Label>().FirstOrDefault().Text + ","; 
          rowsAffected++; 
         } 
        } 
       } 
      } 
      if (rowsAffected == 0) 
      { 
       lblUpdateMsg.Text = "Please select the check box to update the status!!"; 
       lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!"; 
      } 
      else 
      { 
       ACLId = ACLId.ToString().Trim(','); 
       using (SqlConnection con = new SqlConnection(cs)) 
       { 
        cmd = new SqlCommand("VT_ACLReportChangeStatus", con); 
        cmd.CommandType = System.Data.CommandType.StoredProcedure; 
        cmd.CommandTimeout = 3600; 
        //cmd.Parameters.AddWithValue("@ChangeStatus", ddlChangeStatus.SelectedItem.Text.ToString()); 
        //cmd.Parameters.AddWithValue("@ACLId", ACLId); 
        cmd.Parameters.Add(new SqlParameter("@ACLId", SqlDbType.NVarChar,-1)); 
        cmd.Parameters.Add(new SqlParameter("@ChangeStatus", SqlDbType.NVarChar, 50)); 
        cmd.Parameters["@ACLId"].Value = ACLId; 
        cmd.Parameters["@ChangeStatus"].Value = ddlChangeStatus.SelectedItem.Text.ToString(); 
        con.Open(); 
        cmd.ExecuteNonQuery(); 
        con.Close(); 
       } 
       lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!"; 
       lblUpdateMsg.Text = "Detail Saved Successfully!!"; 
       gvACLReport.Visible = false; 
       tableChangeStatus.Visible = false; 
       divReport.Visible = false; 
       // DeleteCompleteACLReport(ACLId); 
      } 
Verwandte Themen