iT邦幫忙

0

[問題解決]Master Detail更新資料問題

  • 分享至 

  • xImage

後續發現是cshtml的傳值有問題,
不曉得為什麼 name一定要限定 poprocess.uid才可以成功。
原本是只有uid而已,改掉過後就可以正常傳值了。

@model PoProcessViewModel
<form method="post" action="/Home/editPoFLow">
    <table id="processTable">
        <thead>
            <tr>
                <th>UID</th>
                <th>Manager</th>
                <th>FlowName</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><input type="text" id="poprocess.uid" name="poprocess.uid" class="form-control" value="@Model.poprocess.uid" readonly/></td>
                <td><input type="text" id="poprocess.manager" name="poprocess.manager" class="form-control" value="@Model.poprocess.manager" readonly /></td>
                <td><input type="text" id="poprocess.flowname" name="poprocess.flowname" class="form-control" value="@Model.poprocess.flowname" /></td>
            </tr>
        </tbody>
    </table>

Hi,我最近剛學Master Detail寫法,
想問一下,當我Detail 資料有新增、刪除列或修改欄位值時,
應該要如何處理,我一開始是參考這個網站,https://www.youtube.com/watch?v=GhjAaPiOp-E
他update寫法是,直接刪除所有資料,在將Form的資料insert進table。

我的寫法也是差不多,但是在刪完,要再新增的時候,就會說沒有東西可以新增。
後來controller 有多寫一個 刪資料前,先將原本的資料放入暫存區。
但是這個方法還是一樣,新增資料會是空值。
求解惑,或是有沒有其他比較好的方法可參考?

BTW,個人還是比較想先知道為何明明有將資料放入暫存,但還是會返回Null的狀況?
HTML

@model Data_Management.Models.Po_Process

<h2>Edit Po_Flow</h2>
<br />
<h3>Process</h3>
<br />
<form method="post" action="/Home/editPoFLow?uid=@Model.uid">
    <table id="processTable">
        <thead>
            <tr>
                <th>UID</th>
                <th>Manager</th>
                <th>FlowName</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <input type="text" id="uid" name="uid" class="form-control" value="@Model.uid" readonly />
                </td>
                <td>
                    <input type="text" id="manager" name="manager" class="form-control" value="@Model.manager" readonly />
                </td>
                <td>
                    <input type="text" id="flowname" name="flowname" class="form-control" value="@Model.flowname" readonly />
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <h3>Sign Flow</h3>
    <br />
    <div id="poSigns">
        <table id="signTable">
            <thead>
                <tr>
                    <th>Sign Name</th>
                    <th>Stage</th>
                    <th>Price</th>
                    <th>C Name</th>
                </tr>
            </thead>
            <tbody>
                @foreach (Po_sign posign in ViewBag.posign_s)
                {
                    <tr>
                        <td>
                            <input type="text" id="signname" name="signname" class="form-control" value="@posign.signname" />
                        </td>
                        <td>
                            <input type="text" id="stage" name="stage" class="form-control" value="@posign.stage" />
                        </td>
                        <td>
                            <input type="text" id="price" name="price" class="form-control" value="@posign.price" />
                        </td>
                        <td>
                            <input type="text" id="cname" name="cname" class="form-control" value="@posign.cname" />
                        </td>
                        <td>
                            <button type="button" class="btn btn-sm btn-secondary invisible" onclick="AddItem(this)">Add</button>
                            <button type="button" class="btn btn-sm btn-danger visible" onclick="DeleteItem(this)">Delete</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
    <input type="hidden" id="hdnLastIndex" value="0" />
    <input class="btn btn-default" type="submit" value="儲存" />
</form>
<script type=text/javascript language=javascript src=https://code.jquery.com/jquery-3.7.0.js></script>

Controller:

        [HttpPost]
        public IActionResult editPoFLow(string uid, PoProcessViewModel model)
        {
            Sign_DBManager dbmanager = new Sign_DBManager();
            try
            {
                // Store the form data in a temporary variable
                var tempPoprocess = model.poprocess;
                var tempPosigns = model.poSigns;
                dbmanager.DeleteSignAndProcess(uid); // Delete existing sign and process
                // Create new process
                dbmanager.NewPoProcess(tempPoprocess);
                foreach (var sign in tempPosigns)
                {
                    sign.uid = tempPoprocess.uid; // Set the uid of sign to the uid of poprocess
                    dbmanager.AddSign(sign); // Add each sign to the database
                }
                return RedirectToAction("Index", new { success = "Process and signs were successfully added." });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return Json(new { error = "An error occurred while adding the process and signs. " + ex.Message });
            }
        }

dbmanager:

        public void NewPoProcess(Po_Process poprocess)
        {
            SqlConnection sqlConnection = new SqlConnection(ConnStr);
            SqlCommand sqlCommand = new SqlCommand(@"insert into Po_Process (uid,manager,flowname) Values(@uid,@manager,@flowname)");
            sqlCommand.Connection = sqlConnection;
            sqlCommand.Parameters.Add(new SqlParameter("@uid", poprocess.uid));
            sqlCommand.Parameters.Add(new SqlParameter("@manager", poprocess.manager));
            sqlCommand.Parameters.Add(new SqlParameter("@flowname", poprocess.flowname));
            sqlConnection.Open();
            sqlCommand.ExecuteNonQuery();
            sqlConnection.Close();
        }
        public void AddSign(Po_sign posign)
        {
            SqlConnection sqlConnection = new SqlConnection(ConnStr);
            SqlCommand sqlCommand = new SqlCommand(
                @"
                INSERT INTO Po_sign (uid, signname, stage, price, cname)
                VALUES (@uid, @signname, @stage, @price, @cname) 

                DECLARE @tmpContent AS varchar(200);
                SET @tmpContent = 'INSERT INTO Po_sign (uid,signname,stage,price,cname) VALUES (''' + @uid + ''', ''' + @signname + ''', ' + CONVERT(varchar(50), @stage) + ', ' + CONVERT(varchar(50), @price) + ', ''' + @cname + ''')'

                INSERT INTO Po_CURD_Log(operation, content, operation_time)
                VALUES ('insert', @tmpContent, GETDATE())");

            sqlCommand.Connection = sqlConnection;
            sqlCommand.Parameters.Add(new SqlParameter("@uid", posign.uid));
            sqlCommand.Parameters.Add(new SqlParameter("@signname", posign.signname));
            sqlCommand.Parameters.Add(new SqlParameter("@stage", posign.stage));
            sqlCommand.Parameters.Add(new SqlParameter("@price", posign.price));
            sqlCommand.Parameters.Add(new SqlParameter("@cname", posign.cname));

            sqlConnection.Open();
            sqlCommand.ExecuteNonQuery();
            sqlConnection.Close();
        }
        public void DeleteSignAndProcess(string uid)
        {
            SqlConnection sqlConnection = new SqlConnection(ConnStr);
            SqlCommand sqlCommand = new SqlCommand("delete from Po_sign where uid = @uid");
            SqlCommand sqlCommand2 = new SqlCommand("delete from Po_Process where uid = @uid");
            sqlCommand.Connection = sqlConnection;
            sqlCommand.Parameters.Add(new SqlParameter("@uid", uid));
            sqlCommand2.Connection = sqlConnection;
            sqlCommand2.Parameters.Add(new SqlParameter("@uid", uid));
            sqlConnection.Open();
            sqlCommand.ExecuteNonQuery();
            sqlCommand2.ExecuteNonQuery();
            sqlConnection.Close();
        }
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
wdchiang
iT邦新手 2 級 ‧ 2023-10-12 14:59:47
最佳解答

用 Dapper 簡潔又好用,這個是 ChatGPT 產生的 Code,你先試改看看

public void UpdateMasterDetail(int masterId, string newValue1, int detailId, string newValue2)
{
    using (IDbConnection dbConnection = new SqlConnection("YourConnectionString"))
    {
        dbConnection.Open();
        using (var transaction = dbConnection.BeginTransaction())
        {
            try
            {
                // 1. 獲取主記錄
                var masterRecord = dbConnection.QuerySingleOrDefault<MasterRecord>("SELECT * FROM MasterTable WHERE MasterID = @MasterID", new { MasterID = masterId });

                // 2. 獲取詳細記錄
                var detailRecord = dbConnection.QuerySingleOrDefault<DetailRecord>("SELECT * FROM DetailTable WHERE DetailID = @DetailID", new { DetailID = detailId });

                // 3. 更新主記錄
                masterRecord.Column1 = newValue1;
                dbConnection.Execute("UPDATE MasterTable SET Column1 = @Column1 WHERE MasterID = @MasterID", masterRecord, transaction);

                // 4. 更新詳細記錄
                detailRecord.Column2 = newValue2;
                dbConnection.Execute("UPDATE DetailTable SET Column2 = @Column2 WHERE DetailID = @DetailID", detailRecord, transaction);

                // 5. 提交事務
                transaction.Commit();
            }
            catch (Exception)
            {
                // 如果出現錯誤,回滾事務
                transaction.Rollback();
            }
        }
    }
}
rain_yu iT邦新手 1 級 ‧ 2023-10-12 15:07:23 檢舉

感謝分享!
說來難過,我的程式碼也是GPT提供的,但是一直給類似的寫法

rain_yu iT邦新手 1 級 ‧ 2023-10-13 16:10:48 檢舉

我自己找到答案了,我看沒有其他人協助解答,所以我還是選你做最佳解

我要發表回答

立即登入回答