Asp.net генерирует неправильный запрос SQL, когда GridView.AllowPaging = "true" - PullRequest
2 голосов
/ 18 июня 2019

Вот необходимый код

<asp:SqlDataSource runat="server"
    ID="StuffDataSource"
    SelectCommand="select employeeID,lastName, firstName, titleOfCourtesy, birthDate, hireDate, address, city, country, homePhone from Employees"
    UpdateCommand="update Employees set lastName=@lastName, firstName=@firstName, address=@address, city=@city, country=@country, homePhone=@homePhone where employeeID=@employeeID"
    DeleteCommand="delete from Employees where employeeID=@employeeID" 
    ConnectionString="<%$ connectionStrings:NorthwindSqlString %>"
    FilterExpression="(lastName like '%{0}%' or firstName like '%{0}%') and country like '%{1}%'"
    OnFiltering="StuffDataSource_Filtering">
    <FilterParameters>
        <asp:ControlParameter Name="Name" ControlId="keyword" PropertyName="Value" DefaultValue="%"/>
        <asp:ControlParameter Name="Country" ControlId="country" PropertyName="Value" DefaultValue="%"/>
    </FilterParameters>
</asp:SqlDataSource>

<asp:GridView runat="server" 
    ID="StuffGridView" 
    DataSourceID="StuffDataSource" 
    OnRowCommand="StufGridView_RowCommand"
    DataKeyNames="employeeID"
    AutoGenerateColumns="false" 
    AllowPaging="true" PageSize="20">
    <Columns>
        <asp:TemplateField HeaderText="序号">
            <ItemTemplate>
                <asp:Label runat="server" Text='<%# (Container.DataItemIndex + 1).ToString() %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="employeeID" HeaderText="id" Visible="false" />
        <asp:BoundField DataField="lastName" HeaderText="名" />
        <asp:BoundField DataField="firstName" HeaderText="姓" />
        <asp:BoundField DataField="titleOfCourtesy" ReadOnly="true" HeaderText="性别" />
        <asp:BoundField DataField="birthDate" HeaderText="出生日期" ReadOnly="true" Visible="false" />
        <asp:BoundField DataField="hireDate" HeaderText="雇用日期" ReadOnly="true" />
        <asp:BoundField DataField="address" HeaderText="地址" />
        <asp:BoundField DataField="city" HeaderText="城市" />
        <asp:BoundField DataField="country" HeaderText="国籍" />
        <asp:BoundField DataField="homePhone" HeaderText="联系" />
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button runat="server" ID="Edit" Text="编辑" CommandName="Edit" CommandArgument='<%# Container.DataItemIndex.ToString() %>' Visible='<%# StuffGridView.EditIndex != Container.DataItemIndex ? true : false %>' />
                <asp:Button runat="server" ID="Delete" Text="删除" CommandName="RequestDelete" CommandArgument='<%# Container.DataItemIndex.ToString() + "," + Eval("firstName").ToString() + " " + Eval("lastName").ToString() %>' Visible='<%# StuffGridView.EditIndex != Container.DataItemIndex ? true : false %>' />
                <asp:Button runat="server" ID="Update" Text="更新" CommandName="Update" CommandArgument='<%# Container.DataItemIndex.ToString() %>' Visible='<%# StuffGridView.EditIndex == Container.DataItemIndex ? true : false %>' />
                <asp:Button runat="server" ID="Cancel" Text="取消" CommandName="Cancel" CommandArgument='<%# Container.DataItemIndex.ToString() %>' Visible='<%# StuffGridView.EditIndex == Container.DataItemIndex ? true : false %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Давайте сосредоточимся на SqlDataSource.DeleteCommand и GridView.AllowPaging.

Когда GridView.AllowPaging="false", я могу нормально удалить запись. Но когда я установил GridView.AllowPaging="true", я не могу удалить запись, кроме записи на первой странице и получить эту ошибку от SQL SERVER

Должен объявлять скалярную переменную «@employeeID» в операторе удаления

Но я думаю, что все подготовлено. DataKeyNames установлен на employeeID, BoundField включает DataField на employeeID. И если есть какие-то ошибки, почему это работает, когда для AllowPaging установлено значение false?

Итак, я хочу знать, какие запросы на самом деле получает СЕРВЕР SQL. Я запустил Profiler в студии управления SQL SERVER. Вот результат:

AllowPaging="false" -> удалить записи на любой странице

AllowPaging="true" -> удалить записи на первой странице

exec sp_executesql N'delete from Employees where employeeID=@employeeID',N'@employeeID int',@employeeID=37

AllowPaging="true" -> удалять записи на любой странице, кроме первой страницы

delete from Employees where employeeID=@employeeID

Так почему же Asp.Net не может сгенерировать правильный запрос SQL при AllowPaging = "true" и удалить записи на любой странице, кроме первой? Я не могу понять, а как избежать этой проблемы?

1 Ответ

1 голос
/ 18 июня 2019

В этой строке:

<asp:Button runat="server" ID="Delete" Text="删除" CommandName="RequestDelete" CommandArgument='<%# Container.DataItemIndex.ToString() + "," + Eval("firstName").ToString() + " " + Eval("lastName").ToString() %>' Visible='<%# StuffGridView.EditIndex != Container.DataItemIndex ? true : false %>' />

Возможно, проблема связана с DataItemIndex. Согласно это , DataTable не знает, на какой странице вы находитесь. Таким образом, вы должны установить правильный индекс по формуле смещения.

Попробуйте что-то вроде этого:

<asp:Button runat="server" ID="Delete" Text="删除" CommandName="RequestDelete" CommandArgument='<%# Container.DataItemIndex.ToString() + ((StuffGridView.ActivePage - 1) * StuffGridView.PageSize) + "," + Eval("firstName").ToString() + " " + Eval("lastName").ToString() %>' />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...