none
オプティミスティック同時実行制御を有効にすると更新されない(ListView + DropDownList) RRS feed

  • 質問

  • スレッド「オプティミスティック同時実行制御のチェックを入れると削除が失敗する」を参照し、スレッド「(ソースコードを書かなくても、htmlソースのみで、)ListViewに配置した2つのDropDownListの連携は出来ますか?」のオプティミスティック同時実行制御バージョンを作成しようとしています。

    ItemTemplateとAlternatingItemTemplateのEvalをBindに変更することにより削除はできるようになりましたが、更新が行えません。(更新ボタンを押すと、変更前のデータ表示に戻ってしまいます)

    自動的に作成された、.aspxソースの該当SQL Server DBテーブルのSqlDataSourceのUpdateCommnadを見ると、更新が行われないように見えるのですが、何か細工が必要なのでしょうか?

    開発環境:
    OS: Windows10 Pro 64 bit
    .NET Framework: 4.5.1(Visual Studio上、プロジェクトープロパティの「ターゲット フレームワーク」より)
    .NET Framework: 4.7.2(レジストリ エディターより)
    .NET Framework: 4.7.03190(「Microsoft Visual Studioのバージョン情報」より)
    IIS: 10.0.17763.1
    VIsual Studio: Professional 2017 Version 15.8.9
    Microsoft SQL Server Express (64-bit): 13.0.4224.16 (日本語)

    .aspxソース(SqlDataSourceのUpdateCommnad行)

    UpdateCommand="UPDATE [acct_new] SET [BtnCD] = @BtnCD, [AtkaiCD] = @AtkaiCD WHERE [ActNo] = @original_ActNo AND (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))">

    .aspxソース(全体)

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="GaisaiNewAcctMaitainanceExclusiveControlTest02.WebForm1" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:ListView ID="ListView1" runat="server" DataKeyNames="ActNo" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem" OnItemDataBound="ListView1_ItemDataBound" OnItemInserting="ListView1_ItemInserting" OnItemUpdating="ListView1_ItemUpdating">
                    <AlternatingItemTemplate>
                        <tr style="">
                            <td>
                                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" />
                                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" />
                            </td>
                            <td>
                                <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Bind("BtnCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Bind("AtkaiCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="ActNoLabel" runat="server" Text='<%# Bind("ActNo") %>' />
                            </td>
                        </tr>
                    </AlternatingItemTemplate>
                    <EditItemTemplate>
                        <tr style="">
                            <td>
                                <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" />
                                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="キャンセル" />
                            </td>
                            <td>
                                <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
                                    ConnectionString="<%$ ConnectionStrings:complianceConnectionString2 %>" 
                                    SelectCommand="SELECT [BtnCD] FROM [butn]"></asp:SqlDataSource>
                                <asp:DropDownList ID="BtnCDDropDownListE" runat="server"
                                    DataSourceID="SqlDataSource2"
                                    DataTextField="BtnCD"
                                    DataValueField="BtnCD"
                                    AutoPostBack="True"
                                    SelectedValue='<%# Bind("BtnCD") %>'>
                                </asp:DropDownList>
                            </td>
                            <td>
                                <asp:SqlDataSource ID="SqlDataSource3" runat="server" 
                                    ConnectionString="<%$ ConnectionStrings:complianceConnectionString3 %>" 
                                    SelectCommand="SELECT [AtkaiCD] FROM [atsu] WHERE ([BtnCD] = @BtnCD)">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="BtnCDDropDownListE" Name="BtnCD" PropertyName="SelectedValue" Type="String" />
                    </SelectParameters>
                </asp:SqlDataSource>
                                <asp:DropDownList ID="AtkaiCDDropDownListE" runat="server"
                                    DataSourceID="SqlDataSource3"
                                    DataTextField="AtkaiCD"
                                    DataValueField="AtkaiCD">
                                </asp:DropDownList>
                            </td>
                            <td>
                                <asp:Label ID="ActNoLabel1" runat="server" Text='<%# Eval("ActNo") %>' />
                            </td>
                        </tr>
                    </EditItemTemplate>
                    <EmptyDataTemplate>
                        <table runat="server" style="">
                            <tr>
                                <td>データは返されませんでした。</td>
                            </tr>
                        </table>
                    </EmptyDataTemplate>
                    <InsertItemTemplate>
                        <tr style="">
                            <td>
                                <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="挿入" />
                                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="クリア" />
                            </td>
                            <td>
                                <asp:SqlDataSource ID="SqlDataSource4" runat="server" 
                                    ConnectionString="<%$ ConnectionStrings:complianceConnectionString4 %>" 
                                    SelectCommand="SELECT [BtnCD] FROM [butn]"></asp:SqlDataSource>
                                <asp:DropDownList ID="BtnCDDropDownListI" runat="server"
                                    DataSourceID="SqlDataSource4"
                                    DataTextField="BtnCD"
                                    DataValueField="BtnCD"
                                    AutoPostBack="True">
                                </asp:DropDownList>
                            </td>
                            <td>
                                <asp:SqlDataSource ID="SqlDataSource5" runat="server" 
                                    ConnectionString="<%$ ConnectionStrings:complianceConnectionString5 %>" 
                                    SelectCommand="SELECT [AtkaiCD] FROM [atsu] WHERE ([BtnCD] = @BtnCD)">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="BtnCDDropDownListI" Name="BtnCD" PropertyName="SelectedValue" Type="String" />
                    </SelectParameters>
                </asp:SqlDataSource>
                                <asp:DropDownList ID="AtkaiCDDropDownListI" runat="server"
                                    DataSourceID="SqlDataSource5"
                                    DataTextField="AtkaiCD"
                                    DataValueField="AtkaiCD">
                                </asp:DropDownList>
                            </td>
                            <td>
                                <asp:TextBox ID="ActNoTextBox" runat="server" Text='<%# Bind("ActNo") %>' />
                            </td>
                        </tr>
                    </InsertItemTemplate>
                    <ItemTemplate>
                        <tr style="">
                            <td>
                                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" />
                                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" />
                            </td>
                            <td>
                                <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Bind("BtnCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Bind("AtkaiCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="ActNoLabel" runat="server" Text='<%# Bind("ActNo") %>' />
                            </td>
                        </tr>
                    </ItemTemplate>
                    <LayoutTemplate>
                        <table runat="server">
                            <tr runat="server">
                                <td runat="server">
                                    <table id="itemPlaceholderContainer" runat="server" border="0" style="">
                                        <tr runat="server" style="">
                                            <th runat="server"></th>
                                            <th runat="server">BtnCD</th>
                                            <th runat="server">AtkaiCD</th>
                                            <th runat="server">ActNo</th>
                                        </tr>
                                        <tr id="itemPlaceholder" runat="server">
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                            <tr runat="server">
                                <td runat="server" style="">
                                    <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="">
                            <td>
                                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" />
                                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" />
                            </td>
                            <td>
                                <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Eval("BtnCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Eval("AtkaiCD") %>' />
                            </td>
                            <td>
                                <asp:Label ID="ActNoLabel" runat="server" Text='<%# Eval("ActNo") %>' />
                            </td>
                        </tr>
                    </SelectedItemTemplate>
                </asp:ListView>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConflictDetection="CompareAllValues" 
                    ConnectionString="<%$ ConnectionStrings:complianceConnectionString %>" 
                    DeleteCommand="DELETE FROM [acct_new] WHERE [ActNo] = @original_ActNo AND (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))" 
                    InsertCommand="INSERT INTO [acct_new] ([BtnCD], [AtkaiCD], [ActNo]) VALUES (@BtnCD, @AtkaiCD, @ActNo)" 
                    OldValuesParameterFormatString="original_{0}" 
                    SelectCommand="SELECT [BtnCD], [AtkaiCD], [ActNo] FROM [acct_new]" 
                    UpdateCommand="UPDATE [acct_new] SET [BtnCD] = @BtnCD, [AtkaiCD] = @AtkaiCD WHERE [ActNo] = @original_ActNo AND (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))">
                    <DeleteParameters>
                        <asp:Parameter Name="original_ActNo" Type="String" />
                        <asp:Parameter Name="original_BtnCD" Type="String" />
                        <asp:Parameter Name="original_AtkaiCD" Type="String" />
                    </DeleteParameters>
                    <InsertParameters>
                        <asp:Parameter Name="BtnCD" Type="String" />
                        <asp:Parameter Name="AtkaiCD" Type="String" />
                        <asp:Parameter Name="ActNo" Type="String" />
                    </InsertParameters>
                    <UpdateParameters>
                        <asp:Parameter Name="BtnCD" Type="String" />
                        <asp:Parameter Name="AtkaiCD" Type="String" />
                        <asp:Parameter Name="original_ActNo" Type="String" />
                        <asp:Parameter Name="original_BtnCD" Type="String" />
                        <asp:Parameter Name="original_AtkaiCD" Type="String" />
                    </UpdateParameters>
                </asp:SqlDataSource>
            </div>
        </form>
    </body>
    </html>

    .aspx.cs(コードビハインド)

    using System;
    using System.Data;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace GaisaiNewAcctMaitainanceExclusiveControlTest02
    {
        public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
            {
                if (e.Item.ItemType == ListViewItemType.DataItem)
                {
                    ListViewDataItem item = (ListViewDataItem)e.Item;
                    DropDownList ddl = (DropDownList)item.FindControl("AtkaiCDDropDownListE");
    
                    if (ddl != null)
                    {
                        ddl.SelectedValue = ((DataRowView)item.DataItem)["AtkaiCD"].ToString();
                    }
                }
            }
    
            protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
            {
                Control ctrl = ((ListView)sender).Items[e.ItemIndex].FindControl("AtkaiCDDropDownListE");
    
                if (ctrl != null)
                {
                    e.NewValues["AtkaiCD"] = ((DropDownList)ctrl).SelectedValue;
                }
                else
                {
                    e.Cancel = true;
                }
            }
    
            protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e)
            {
                DropDownList ddl_BtnCD = (DropDownList)e.Item.FindControl("BtnCDDropDownListI");
                DropDownList ddl_AtkaiCD = (DropDownList)e.Item.FindControl("AtkaiCDDropDownListI");
    
                if (ddl_BtnCD != null && ddl_AtkaiCD != null)
                {
                    e.Values["BtnCD"] = ddl_BtnCD.SelectedValue;
                    e.Values["AtkaiCD"] = ddl_AtkaiCD.SelectedValue;
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }
    }


    • 編集済み Herokey 2019年12月9日 6:10 フォントがおかしくなったので、修正した。
    2019年12月9日 6:08

回答

  • > 「SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得」する方法が分かりません。教えてください。

    以下のコードを試してみてください。(もちろん aspx 側で SqlDataSource1 の OnUpdating の設定も必要。分かっていると思いますが念のため)

    protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
    {
        SqlCommand command = (SqlCommand)e.Command;
        var original_BtnCD = command.Parameters["@original_BtnCD"].Value;
        var original_AtkaiCD = command.Parameters["@original_AtkaiCD"].Value;
    }

    UPDATE コマンドの WHERE 句の条件が true にならないということは、パラメータ @original_BtnCD と @original_AtkaiCD に代入される値が問題と思われます。それは上記のハンドラを追加しブレークポイントを設定してデバッガで調べられるはずです。

    SelectedValue='<%# Bind("BtnCD") %>' が設定されている original_BtnCD の方は期待通り元の値(質問者さんが編集する前の値)が取れているが、設定されてない original_AtkaiCD の方は元の値が取得できてない(null になっている)と想像しています。

    試して結果を連絡ください。

    • 回答としてマーク Herokey 2019年12月17日 0:25
    2019年12月16日 5:58
  • そして、EditItemTemplate の AtkaiCD の DropDownList にも、SelectedValue を入れたところ、更新もできるようになり、挿入、更新、削除が出来るようになりました。

    発行して、更新競合を確認したところ、正しく、後に更新をかけた方が弾かれ、更新できませんでした。

     <td>
         <asp:SqlDataSource ID="SqlDataSource3" runat="server"
             ConnectionString="<%$ ConnectionStrings:complianceConnectionString3 %>"
             SelectCommand="SELECT * FROM [atsu] WHERE ([BtnCD] = @BtnCD)">
             <SelectParameters>
                 <asp:ControlParameter
                     ControlID="BtnCDDropDownListE"
                     Name="BtnCD"
                     PropertyName="SelectedValue"
                     Type="String" />
             </SelectParameters>
         </asp:SqlDataSource>
         <asp:DropDownList ID="AtkaiCDDropDownListE" runat="server"
             DataSourceID="SqlDataSource3"
             DataTextField="AtkaiCD"
             DataValueField="AtkaiCD"
             SelectedValue='<%# Bind("AtkaiCD") %>'>
         </asp:DropDownList>
     </td>

    競合により更新されなかった事は、下の文で確認しました。

     protected void SqlDataSource1_Updated(object sender, SqlDataSourceStatusEventArgs e)
     {
         if (e.AffectedRows == 0)
         {
             Response.Write("データ競合が発生しました");
         }
     }



    • 編集済み Herokey 2019年12月16日 7:30 競合確認方法を追記
    • 回答としてマーク Herokey 2019年12月17日 0:26
    2019年12月16日 7:22

すべての返信

  • 同時実行制御違反になるようなことはしてないのに update できないと言ってますか?

    何にせよ WHERE 句の条件が満たされないのが理由だと思いますので、なぜそうなるのかを調べてください。(長いコードを読んでデバッグしてくれというのは負担が大きすぎます。まず質問者さんの方でそのあたりを切り分けしてください)

    何を見れば分かるかは以下の記事が参考になるかもしれません。

    SqlDataSource などのパラメータ
    http://surferonwww.info/BlogEngine/post/2010/09/26/How-a-data-bound-control-passes-parameters-to-data-source-control.aspx


    • 編集済み SurferOnWww 2019年12月9日 6:54 誤字訂正
    2019年12月9日 6:54
  • 何を見れば分かるかですが、SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得できるので、それを調べる手もあります。その方が簡単で分かりやすそうです。
    2019年12月9日 7:41
  • Herokeyさん、こんにちは。フォーラムオペレーターのクモです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    上記のコードをテストしてみましたが、いくつかの問題を発見しました。
    アップデートするときに、コマンドステートメントは少し複雑だと思います。
    また、ListView1_ItemUpdating () イベントに、2 DropDownListの値を得るはずです。

    次は私から修正したコードです:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ThreadDemoConnectionString %>"
                    SelectCommand="SELECT [BtnCD], [AtkaiCD], [ActNo] FROM [acct_new]"
                    UpdateCommand="UPDATE [acct_new] SET BtnCD = @BtnCD, AtkaiCD = @AtkaiCD WHERE ActNo= @ActNo">
                    <UpdateParameters>
                        <asp:Parameter Name="BtnCD" Type="String" />
                        <asp:Parameter Name="AtkaiCD" Type="String" />
                        <asp:Parameter Name="ActNo" Type="String" />
                    </UpdateParameters>
                </asp:SqlDataSource>
    
    protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
            {
                Control ctrl = ((ListView)sender).Items[e.ItemIndex].FindControl("AtkaiCDDropDownListE");
                Control ctrl1 = ((ListView)sender).Items[e.ItemIndex].FindControl("BtnCDDropDownListE");
    
                if (ctrl != null)
                {
                    e.NewValues["AtkaiCD"] = ((DropDownList)ctrl).SelectedValue;
                    e.NewValues["BtnCD"] = ((DropDownList)ctrl).SelectedValue;
                }
                else
                {
                    e.Cancel = true;
                }
            }

    結果は次のデモをご参照まで。


    どうぞよろしくお願いいたします。 


    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年12月13日 6:42
    モデレータ
  • > アップデートするときに、コマンドステートメントは少し複雑だと思います。

    質問者さんは楽観的同時実行制御をしたいとのことです。さらに BtnCD, AtkaiCD フィールドに NULL を許可しているようで、質問にあったような複雑な WHERE 句にならざるを得ません。

    質問に書いてある UPDATE コマンドは SqlDataSource のウィザードを使って自動生成したものでしょうし、楽観的同時実行制御をする目的には間違ってないと思います。
    2019年12月13日 7:06
  • クモさん

    回答ありがとうございます。

    しかしながら、UpdateCommnadのWHERE句をその様にしてしまうと、オプティミスティック同時実行制御にならないのではないでしょうか?つまり、2台のPCで変更を行うと、先に行ったPCの更新が、後に行ったPCの更新で上書きされてしまう。

    (ListView1_ItemUpdating () イベントに、2 DropDownListの値を得てはいませんが、)以前と今回、試しました。

    2019年12月13日 7:38
  • 質問者さんはここを放置して去ってしまったと思っていてんですが、私のアドバイスを聞いて解決のための努力を続けたいという希望があるなら、私のレスにフィードバックを返してください。返さないのであれば、自分は撤退します。
    2019年12月13日 8:13
  • > アップデートするときに、コマンドステートメントは少し複雑だと思います。

    質問者さんは楽観的同時実行制御をしたいとのことです。さらに BtnCD, AtkaiCD フィールドに NULL を許可しているようで、質問にあったような複雑な WHERE 句にならざるを得ません。

    質問に書いてある UPDATE コマンドは SqlDataSource のウィザードを使って自動生成したものでしょうし、楽観的同時実行制御をする目的には間違ってないと思います。

    はい、SqlDataSourceのウィザードで自動生成しました。

    そして、「acct_new」テーブル定義上、「BtnCD」、「AtkaiCD」フィールドのNULLは許可しています。

    また、放置しているのではなく、「SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得」を、どこで、どうやったら、できるかを、試行錯誤しています。

    2019年12月13日 8:32
  • > 「SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得」を、どこで、どうやったら、できるかを、試行錯誤しています。

    少なくとも一番最初に聞いた、

    > 同時実行制御違反になるようなことはしてないのに update できないと言ってますか?

    には即答できるでしょう。聞いたことには答えてもらわないと話が噛み合わなくなります。

    それから、パラメータの調べ方が分からなければ聞いてください。無言はとにかく NG です。

    UPDATE コマンドは以下のようになっているそうですが、楽観的同時実行制御を有効にした結果 3 行目の AND 以降が追加されたのですよね。(前の楽観的同時実行制御をしてないときのコードと比べてみてください)

    UPDATE [acct_new] 
      SET [BtnCD] = @BtnCD, [AtkaiCD] = @AtkaiCD 
      WHERE [ActNo] = @original_ActNo AND 
      (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND 
      (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))

    前は問題なく UPDATE できていたということは、追加された上の 4 ~ 5 行の条件が true にならないということのはずなので、それを調べてくださいと言ったのですが、そこのところの理解は良いですか?

    SqlDataSource.Updating イベントのハンドラの引数から SqlCommad が取得できますので、それから SqlParameter を取得して、その Value プロパティで @original_BtnCD と @original_AtkaiCD の値が分かるので、それを見たらヒントが見つかるかもしれないということです。

    ところで、一気に DropDownList を使うことで進めないで、デザイナで一行もコードを書かないで生成されるテキストボックスベースでは試してみましたか?

    2019年12月13日 9:22
  • >> 同時実行制御違反になるようなことはしてないのに update できないと言ってますか?
    > には即答できるでしょう。聞いたことには答えてもらわないと話が噛み合わなくなります。

    はい、単独のVisualStudioからの更新において update できません。
    回答しておらず、失礼しました。


    > それから、パラメータの調べ方が分からなければ聞いてください。無言はとにかく NG です。

    「SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得」する方法が分かりません。教えてください。


    > UPDATE コマンドは以下のようになっているそうですが、楽観的同時実行制御を有効にした結果 3 行目の AND 以降が追加されたのですよね。(前の楽観的同時実行制御をしてないときのコードと比べてみてください)

    はい、楽観的同時実行制御が無効のものには3行目と4行目はなく、楽観的同時実行制御が有効のものには3行目と4行目があります。


    > 前は問題なく UPDATE できていたということは、追加された上の 4 ~ 5 行の条件が true にならないということのはずなので、それを調べてくださいと言ったのですが、そこのところの理解は良いですか?

    以前は楽観的同時実行制御を無効にしていました。


    > ところで、一気に DropDownList を使うことで進めないで、デザイナで一行もコードを書かないで生成されるテキストボックスベースでは試してみましたか?

    試していません。試してみます。

    ありがとうございます。



    • 編集済み Herokey 2019年12月16日 4:48
    2019年12月16日 4:47
  • > 「SqlDataSource の Updating イベントのハンドラで SqlCommand オブジェクトを取得」する方法が分かりません。教えてください。

    以下のコードを試してみてください。(もちろん aspx 側で SqlDataSource1 の OnUpdating の設定も必要。分かっていると思いますが念のため)

    protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
    {
        SqlCommand command = (SqlCommand)e.Command;
        var original_BtnCD = command.Parameters["@original_BtnCD"].Value;
        var original_AtkaiCD = command.Parameters["@original_AtkaiCD"].Value;
    }

    UPDATE コマンドの WHERE 句の条件が true にならないということは、パラメータ @original_BtnCD と @original_AtkaiCD に代入される値が問題と思われます。それは上記のハンドラを追加しブレークポイントを設定してデバッガで調べられるはずです。

    SelectedValue='<%# Bind("BtnCD") %>' が設定されている original_BtnCD の方は期待通り元の値(質問者さんが編集する前の値)が取れているが、設定されてない original_AtkaiCD の方は元の値が取得できてない(null になっている)と想像しています。

    試して結果を連絡ください。

    • 回答としてマーク Herokey 2019年12月17日 0:25
    2019年12月16日 5:58
  • > UPDATE コマンドの WHERE 句の条件が true にならないということは、パラメータ @original_BtnCD と @original_AtkaiCD に代入される値が問題と思われます。それは上記のハンドラを追加しブレークポイントを設定してデバッガで調べられるはずです。

    SelectedValue='<%# Bind("BtnCD") %>' が設定されている original_BtnCD の方は期待通り元の値(質問者さんが編集する前の値)が取れているが、設定されてない original_AtkaiCD の方は元の値が取得できてない(null になっている)と想像しています。


    確認したところ、original_BtnCD には(選択BtnCDの)値が入っていましたが、original_AtkaiCD は NULL でした。


    また、TextBox で確認したところ、当初、「挿入と更新はできる。削除ができない。」という状態でしたが、「AlternatingItemTemplate」と「ItemTemplate」内の「Eval」を「Bind」に交換した後は、削除もできるようになりました。


    ありがとうございます。


    念のためですが、aspx での SqlDataSource1 の OnUpdating の設定とは、下の図のことですよね?



    • 編集済み Herokey 2019年12月16日 6:38
    2019年12月16日 6:35
  • そして、EditItemTemplate の AtkaiCD の DropDownList にも、SelectedValue を入れたところ、更新もできるようになり、挿入、更新、削除が出来るようになりました。

    発行して、更新競合を確認したところ、正しく、後に更新をかけた方が弾かれ、更新できませんでした。

     <td>
         <asp:SqlDataSource ID="SqlDataSource3" runat="server"
             ConnectionString="<%$ ConnectionStrings:complianceConnectionString3 %>"
             SelectCommand="SELECT * FROM [atsu] WHERE ([BtnCD] = @BtnCD)">
             <SelectParameters>
                 <asp:ControlParameter
                     ControlID="BtnCDDropDownListE"
                     Name="BtnCD"
                     PropertyName="SelectedValue"
                     Type="String" />
             </SelectParameters>
         </asp:SqlDataSource>
         <asp:DropDownList ID="AtkaiCDDropDownListE" runat="server"
             DataSourceID="SqlDataSource3"
             DataTextField="AtkaiCD"
             DataValueField="AtkaiCD"
             SelectedValue='<%# Bind("AtkaiCD") %>'>
         </asp:DropDownList>
     </td>

    競合により更新されなかった事は、下の文で確認しました。

     protected void SqlDataSource1_Updated(object sender, SqlDataSourceStatusEventArgs e)
     {
         if (e.AffectedRows == 0)
         {
             Response.Write("データ競合が発生しました");
         }
     }



    • 編集済み Herokey 2019年12月16日 7:30 競合確認方法を追記
    • 回答としてマーク Herokey 2019年12月17日 0:26
    2019年12月16日 7:22
  • 前者に連動して動く後者の DropDownList にはそのような設定をしなかった理由はエラーが出るからです。忘れましたか? それとも質問者さんへの環境ではエラーにならない?

    2019年12月16日 8:11
  • > 前者に連動して動く後者の DropDownList にはそのような設定をしなかった理由はエラーが出るからです。忘れましたか? それとも質問者さんへの環境ではエラーにならない?

    忘れていました。スレッド「オプティミスティック同時実行制御を有効にすると更新されない(ListView + DropDownList)」の下の記事ですか?私もちょっと異なるエラーが出ていましたね。

    しかし、今回のテストの範囲ではエラーは出ませんでした。


    そうすると、初期画面では 2 つの DropDownList に期待通り選択された項目が表示されますが、そこから 1 つ目の DropDownList のアイテムの選択を変更すると "System.InvalidOperationException: Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データバインドされたコントロールのコンテキストでのみ使用することができます。" という DetailsView の場合と同じエラーになります。

    2019年12月16日 8:42
  • > 念のためですが、aspx での SqlDataSource1 の OnUpdating の設定とは、下の図のことですよね?

    違います。それは ListView のイベント。

    話が通じないのは何故でしょう???????


    2019年12月16日 8:54
  • 違います。それは ListView のイベント。話が通じないのは何故でしょう???????

    間違えました。こちらですね!

    2019年12月16日 8:59
  • エラーが出ないなら好きにしてください。
    2019年12月16日 9:09