2013-07-05 4 views
3

У меня есть GridView, связанный с SqlDataSource. Я сталкиваюсь с проблемами с выполнением UpdateCommand, кажется, что он выполняется дважды. Когда я просматриваю код в событии gvChecklist_RowUpdating, я вижу, что все работает правильно, и хранимая процедура выполняется. Я проверил, что хранимая процедура работает правильно, так как в таблице db есть новая запись. Когда это событие выходит, хотя, я получаю следующее сообщение об ошибке:SqlDataSource UpdateCommand Called Twice

Procedure or function usp_TestLogInsert has too many arguments specified.

Я вижу, что событие Обновления на источнике данных вызываются после события RowUpdating. Я попытался отменить это событие, чтобы предотвратить попытки множественного обновления, но затем ничего не происходит, и GridView остается в режиме редактирования.

ASP код

<asp:UpdatePanel ID="upGridView" runat="server" UpdateMode="Conditional"> 
    <ContentTemplate> 
    <asp:GridView ID="gvChecklist" runat="server" 
        AutoGenerateColumns="false" DataSourceID="dsChecklist" 
        AutoGenerateEditButton="true" 
        onrowupdating="gvChecklist_RowUpdating"> 
     <Columns> 
     <asp:TemplateField HeaderText="Status"> 
      <ItemTemplate> 
      <asp:Label ID="lblStatus" runat="server" 
         Text='<%#Eval("Status") %>' /> 
      </ItemTemplate> 
      <EditItemTemplate> 
      <asp:DropDownList ID="ddStatus" runat="server" 
           DataTextField="Status" 
           DataValueField="ID" 
           DataSourceID="dsStatus" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:BoundField DataField="Division" 
         HeaderText="Division" 
         readonly="true" /> 
     <asp:BoundField DataField="Application" 
         HeaderText="Application" 
         readonly="true" /> 
     <asp:BoundField DataField="Task" 
         HeaderText="Task" 
         readonly="true" /> 
     <asp:BoundField DataField="TestedBy" 
         HeaderText="Tested By" 
         readonly="true"/> 
     <asp:BoundField DataField="Notes" 
         HeaderText="Notes" 
         ReadOnly="false"/> 
     <asp:BoundField DataField="JiraTicket" 
         HeaderText="JIRA Ticket" 
         readonly="false" /> 
     <asp:BoundField DataField="ID" /> 
     </Columns> 
    </asp:GridView> 
    </ContentTemplate> 
    <Triggers> 
    <asp:PostBackTrigger ControlID="gvChecklist" /> 
    </Triggers> 
</asp:UpdatePanel> 
</td> 
</tr> 
</table> 

<asp:SqlDataSource ID="dsChecklist" 
        SelectCommand=" SELECT l.ID, d.division, c.Context AS Application, t.Task, l.TestedBy, l.Notes, l.JiraTicket, s.Status 
            FROM Automation.manual.Tests t 
            OUTER APPLY 
             (SELECT TOP 1 * 
              FROM Automation.manual.TestLog l 
              WHERE l.TestID = t.ID 
              ORDER BY l.Date DESC) l 
            INNER JOIN Automation.dbo.Context c ON c.ID = t.Context 
            INNER JOIN Automation.dbo.Division d ON d.ID = t.Division 
            LEFT OUTER JOIN Automation.manual.Status s ON s.ID = l.Status" 
        runat="server"         
        ConnectionString="<%$ ConnectionStrings:AutomationDBConnectionString %>" 
        onupdating="dsChecklist_Updating" > 
    <UpdateParameters> 
    <asp:Parameter Name="Status" DbType="Int32" /> 
    <asp:Parameter Name="TestID" DbType="Int32" /> 
    <asp:Parameter Name="TestedBy" DbType="String" /> 
    <asp:Parameter Name="Notes" DbType="String" /> 
    <asp:Parameter Name="JiraTicket" DbType="String" /> 
    <asp:Parameter Name="Build" DbType="String" /> 
    </UpdateParameters> 
</asp:SqlDataSource> 

C#

protected void gvChecklist_RowUpdating(object sender, GridViewUpdateEventArgs e) 
{ 
    SQLConnections sql = new SQLConnections(); 
    SqlDataSource dsChecklist = (SqlDataSource)LoginView1.FindControl("dsChecklist"); 
    var dd = (DropDownList)gvChecklist.Rows[e.RowIndex].FindControl("ddStatus"); 
    var status = dd.SelectedValue; 
    var testID = sql.SQLSelectSingle(String.Format("SELECT ID FROM Automation.manual.Tests WHERE Task = '{0}'", (String)e.OldValues["Task"]), "pwautosql01"); 
    string user = Page.User.Identity.Name; 
    string notes = (String)e.NewValues["Notes"]; 
    string jira = (String)e.NewValues["JiraTicket"]; 
    var dbID = e.NewValues["ID"]; 
    string build = "TODO"; 

    if (dbID == null) //Record does not exist in TestLog, INSERT a new one 
    { 
     dsChecklist.UpdateCommand = "[Automation].[manual].[usp_TestLogInsert]"; 
     dsChecklist.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure; 

     dsChecklist.UpdateParameters["Status"].DefaultValue = status; 
     dsChecklist.UpdateParameters["TestID"].DefaultValue = testID; 
     dsChecklist.UpdateParameters["TestedBy"].DefaultValue = user; 
     dsChecklist.UpdateParameters["Notes"].DefaultValue = notes; 
     dsChecklist.UpdateParameters["JiraTicket"].DefaultValue = jira; 
     dsChecklist.UpdateParameters["Build"].DefaultValue = build; 

     gvChecklist.DataBind(); 
    } 
    //else //Record already exists in TestLog. UPDATE 
    //{ 
    //TODO 
    //} 
} 

EDIT: Я использовал SQL Profiler, чтобы увидеть, какие параметры будут отправлены в хранимой процедуре. Несмотря на то, что INSERT происходит и создается новая запись, отправляется дополнительный параметр с именем ID. Я никогда явно не посылаю этот параметр, но кажется, что он создан, так как у меня есть идентификатор BoundField с именем в моем GridView. Чтобы создать исходный вопрос, есть ли способ, чтобы UpdateCommand игнорировал этот BoundField, чтобы он автоматически не использовал его в качестве параметра?

+0

Вы можете написать код для 'dsChecklist_Updating'? – Tim

+0

Это событие пуста. Я создал его в коде, чтобы убедиться, что он попал. Похоже, что UpdateCommand выполняется в моем событии RowUpdating, но после вызова события dsChecklist_Updating. – Andrew

+0

Отправьте TSQL для '[Automation]. [Manual]. [Usp_TestLogInsert]'. – Hogan

ответ

1

После использования SQL Profiler я обнаружил, что BoundField ID был добавлен как параметр UpdateCommand неявно. Изменение этого поля в TemplateItem устраняет эту проблему.

     <asp:TemplateField> 
         <ItemTemplate> 
          <asp:TextBox ID="tbId" Text='<%#Eval("ID") %>' ReadOnly="true" runat="server"></asp:TextBox> 
         </ItemTemplate> 
         </asp:TemplateField>