4

楽観的な同時実行性を持つ単純な ListView を作成しようとしています。VS で自動生成された Delete、Insert、Update ステートメントを使用します (挿入する 1 つの変更を除く: コードを参照)。挿入と編集は正常に機能し、データベースにコミットします。削除しようとすると、次のエラーが発生します。

削除コマンドが SqlDataSource 'MySourceHere' のすべての値を比較するように指定しましたが、値に渡されたディクショナリが空です。有効なディクショナリを渡して削除するか、モードを OverwriteChanges に変更してください。

「CompareAllValues」を「OverwriteChanges」に変更して、同時実行作業を後で延期しようとしましたが、Update コマンドと Delete コマンドが「中断」され、ListView が古い値で更新されたように見えます。この問題を解決した唯一のスレッドは、「OverwriteChanges」に変更するか、「DataKeyNames」を宣言していない人でした。関連するマークアップを以下に示します (期待しています)。

何かご意見は?

<asp:SqlDataSource ID="ManageUsersSource" runat="server" 
    ConflictDetection="CompareAllValues" 
    ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
        DeleteCommand="DELETE FROM [DUSER] WHERE [userid] = ? AND (([username] = ?) OR ([username] IS NULL AND ? IS NULL)) AND (([userpass] = ?) OR ([userpass] IS NULL AND ? IS NULL))" 
    InsertCommand="INSERT INTO [DUSER] ([username], [userpass]) VALUES (?, ?)" 
    OldValuesParameterFormatString="original_{0}" 
    ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>" 
    SelectCommand="SELECT * FROM [DUSER] ORDER BY [userid] ASC" 
    UpdateCommand="UPDATE [DUSER] SET [username] = ?, [userpass] = ? WHERE [userid] = ? AND (([username] = ?) OR ([username] IS NULL AND ? IS NULL)) AND (([userpass] = ?) OR ([userpass] IS NULL AND ? IS NULL))">
    <DeleteParameters>
        <asp:Parameter Name="original_userid" Type="Int16" />
        <asp:Parameter Name="original_username" Type="String" />
        <asp:Parameter Name="original_username" Type="String" />
        <asp:Parameter Name="original_userpass" Type="String" />
        <asp:Parameter Name="original_userpass" Type="String" />
    </DeleteParameters>
    <InsertParameters>
    <%--This is removed since [userid] is an automatically generated index.--%>
        <%--<asp:Parameter Name="userid" Type="Int16" />--%>
        <asp:Parameter Name="username" Type="String" />
        <asp:Parameter Name="userpass" Type="String" />
    </InsertParameters>
    <UpdateParameters>
        <asp:Parameter Name="username" Type="String" />
        <asp:Parameter Name="userpass" Type="String" />
        <asp:Parameter Name="original_userid" Type="Int16" />
        <asp:Parameter Name="original_username" Type="String" />
        <asp:Parameter Name="original_username" Type="String" />
        <asp:Parameter Name="original_userpass" Type="String" />
        <asp:Parameter Name="original_userpass" Type="String" />
    </UpdateParameters>
</asp:SqlDataSource>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="userid" 
    DataSourceID="ManageUsersSource" InsertItemPosition="LastItem">
    <AlternatingItemTemplate>
        <tr style="background-color:#FFF8DC;">
            <td>
                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" 
                    Text="Delete" />
                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
            </td>
            <td>
                <asp:Label ID="useridLabel" runat="server" Text='<%# Eval("userid") %>' />
            </td>
            <td>
                <asp:Label ID="usernameLabel" runat="server" Text='<%# Eval("username") %>' />
            </td>
            <td>
                <asp:Label ID="userpassLabel" runat="server" Text='<%# Eval("userpass") %>' />
            </td>
        </tr>
    </AlternatingItemTemplate>
    <EditItemTemplate>
        <tr style="background-color:#008A8C;color: #FFFFFF;">
            <td>
                <asp:Button ID="UpdateButton" runat="server" CommandName="Update" 
                    Text="Update" />
                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
                    Text="Cancel" />
            </td>
            <td>
                <asp:Label ID="useridLabel1" runat="server" Text='<%# Eval("userid") %>' />
            </td>
            <td>
                <asp:TextBox ID="usernameTextBox" runat="server" 
                    Text='<%# Bind("username") %>' />
            </td>
            <td>
                <asp:TextBox ID="userpassTextBox" runat="server" 
                    Text='<%# Bind("userpass") %>' />
            </td>
        </tr>
    </EditItemTemplate>
    <EmptyDataTemplate>
        <table runat="server" 
            style="background-color: #FFFFFF;border-collapse: collapse;border-color: #999999;border-style:none;border-width:1px;">
            <tr>
                <td>
                    No data was returned.</td>
            </tr>
        </table>
    </EmptyDataTemplate>
    <InsertItemTemplate>
        <tr style="">
            <td>
                <asp:Button ID="InsertButton" runat="server" CommandName="Insert" 
                    Text="Insert" />
                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
                    Text="Clear" />
            </td>
            <td>
                &nbsp;</td>
            <td>
                <asp:TextBox ID="usernameTextBox" runat="server" 
                    Text='<%# Bind("username") %>' />
            </td>
            <td>
                <asp:TextBox ID="userpassTextBox" runat="server" 
                    Text='<%# Bind("userpass") %>' />
            </td>
        </tr>
    </InsertItemTemplate>
    <ItemTemplate>
        <tr style="background-color:#DCDCDC;color: #000000;">
            <td>
                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" 
                    Text="Delete" />
                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
            </td>
            <td>
                <asp:Label ID="useridLabel" runat="server" Text='<%# Eval("userid") %>' />
            </td>
            <td>
                <asp:Label ID="usernameLabel" runat="server" Text='<%# Eval("username") %>' />
            </td>
            <td>
                <asp:Label ID="userpassLabel" runat="server" Text='<%# Eval("userpass") %>' />
            </td>
        </tr>
    </ItemTemplate>
    <LayoutTemplate>
        <table runat="server">
            <tr runat="server">
                <td runat="server">
                    <table ID="itemPlaceholderContainer" runat="server" border="1" 
                        style="background-color: #FFFFFF;border-collapse: collapse;border-color: #999999;border-style:none;border-width:1px;font-family: Verdana, Arial, Helvetica, sans-serif;">
                        <tr runat="server" style="background-color:#DCDCDC;color: #000000;">
                            <th runat="server">
                            </th>
                            <th runat="server">
                                userid</th>
                            <th runat="server">
                                username</th>
                            <th runat="server">
                                userpass</th>
                        </tr>
                        <tr ID="itemPlaceholder" runat="server">
                        </tr>
                    </table>
                </td>
            </tr>
            <tr runat="server">
                <td runat="server" 
                    style="text-align: center;background-color: #CCCCCC;font-family: Verdana, Arial, Helvetica, sans-serif;color: #000000;">
                    <asp:DataPager ID="DataPager1" runat="server">
                        <Fields>
                            <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" 
                                ShowLastPageButton="True" />
                        </Fields>
                    </asp:DataPager>
                </td>
            </tr>
        </table>
    </LayoutTemplate>
    <SelectedItemTemplate>
        <tr style="background-color:#008A8C;font-weight: bold;color: #FFFFFF;">
            <td>
                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" 
                    Text="Delete" />
                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
            </td>
            <td>
                <asp:Label ID="useridLabel" runat="server" Text='<%# Eval("userid") %>' />
            </td>
            <td>
                <asp:Label ID="usernameLabel" runat="server" Text='<%# Eval("username") %>' />
            </td>
            <td>
                <asp:Label ID="userpassLabel" runat="server" Text='<%# Eval("userpass") %>' />
            </td>
        </tr>
    </SelectedItemTemplate>
</asp:ListView>

4

3 に答える 3

4

ItemTemplate/AlternatingItemTemplateで「 Eval 」の代わりに「 Bind 」を使用するように非主キー フィールドを変更する(編集テンプレートと同様) ことは、古い値を適切に渡すために明らかに必要でした。

これは、完全に理解せずに自動生成されたマークアップを使用したケースでした (私はまだ理解していません)。

于 2012-06-06T15:56:22.587 に答える
0

更新コマンドと削除コマンドを簡素化してみてください。ユーザー ID (DataKeyName) は自動的に生成され、一意であるため、追加のパラメーターは必要ありません。

したがって、あなたの UpdateCommand は

"UPDATE [DUSER] SET [username] = ?, [userpass] = ? WHERE [userid] = ?"

次のパラメータを使用:-

<UpdateParameters>
    <asp:Parameter Name="userid" Type="Int16" />
    <asp:Parameter Name="username" Type="String" />
    <asp:Parameter Name="userpass" Type="String" />
</UpdateParameters>

あなたのDeleteCommandは

"DELETE FROM [DUSER] WHERE [userid] = ?"

次のパラメータを使用:-

<DeleteParameters>
    <asp:Parameter Name="userid" Type="Int16" />
</DeleteParameters>
于 2012-06-05T20:26:37.643 に答える
0

申し訳ありませんが、?s を変更するのを忘れていました。オプティミスティック コンカレンシーが必要です。

"UPDATE [DUSER] SET [username] = @username, [userpass] = @userpass WHERE [userid] = @userid And [username] = @original_username And [userpass] = @original_userpass"

"DELETE FROM [DUSER] WHERE [userid] = @userid And [username] = @original_username And [userpass] = @original_userpass"

もちろん、行が更新/削除されたかどうかを確認する必要があります。

InserCommand も次のようにする必要があります:-

"INSERT INTO [DUSER] ([username], [userpass]) VALUES (@username, @userpass)"

username と userpass が null を許可しないように設定されていると仮定すると (この場合はそうあるべきです)、いずれかのパラメーターが null の場合、コマンドは失敗します。

これを回避する<asp:RequiredFieldValidator>には、usernameTextBox コントロールと userpassTextBox コントロールのそれぞれに を追加して、クライアント側の検証を提供します。

パラメータ名と一致するように、TextBox コントロールの ID も変更する必要があります。

null 値を処理する必要がある場合は、null 比較が使用される生成されたクエリの他の部分が必要になり、?s を適切なパラメーターに置き換えます。

于 2012-06-05T22:06:05.743 に答える