後續發現是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();
}
用 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();
}
}
}
}