| 關係 | 級聯新增 | 級聯更新 | 級聯刪除 |
|---|---|---|---|
| 一對多 (Order → Order_Details) | ✅ 內建支援 | ✅ 智能追蹤 | ❌ 需手動處理 |
| 一對一 | ✅ | ✅ | ❌ |
| 多對多 | ✅ (透過關聯實體) | ✅ | ❌ |

protected void btnCascadeAdd_Click(object sender, EventArgs e)
{
using (var db = new DataClasses2DataContext())
{
Orders order = new Orders
{
ShipCountry = "China",
CustomerID = "ALFKI",
EmployeeID = 1,
ShipVia = 1
};
for (int i = 1; i < 5; i++)
{
order.Order_Details.Add(new Order_Details
{
Discount = 0.2f,
Quantity = (short)i,
ProductID = i
});
}
db.Orders.InsertOnSubmit(order);
db.SubmitChanges(); // 單一 Transaction 完成父子寫入
}
}
SQL Profiler 驗證:先 INSERT Order 取得 Identity,再批次 INSERT Order_Details,隱式交易保證原子性。
protected void btnCascadeUpdate_Click(object sender, EventArgs e)
{
using (var db = new DataClasses2DataContext())
{
Orders order = db.Orders.Single(o => o.OrderID == 11120);
order.ShipAddress = "江蘇省昆山市安博路1號";
foreach (var detail in order.Order_Details)
{
detail.Discount = 0.1f; // 批量修改子物件
}
db.SubmitChanges(); // 僅發出必要 UPDATE 陳述式
}
}
LINQ to SQL 比較原始值與目前值,只更新實際變更的欄位,產生精簡 SQL。
protected void btnCascadeDelete_Click(object sender, EventArgs e)
{
using (var db = new DataClasses2DataContext())
{
Orders order = db.Orders.Single(o => o.OrderID == 11127);
db.Order_Details.DeleteAllOnSubmit(order.Order_Details); // 先刪子
db.Orders.DeleteOnSubmit(order); // 再刪父
db.SubmitChanges();
}
}
<Association ... DeleteOnNull="true" />ON DELETE CASCADEdb.Orders.DeleteOnSubmit(order); db.SubmitChanges();原理:DeleteOnNull 允許子物件在記憶體中成為孤兒,提交時資料庫級聯刪除。
protected void btnComplexOp_Click(object sender, EventArgs e)
{
using (var db = new DataClasses2DataContext())
{
Orders order = db.Orders.Single(o => o.OrderID == 11126);
// 父屬性修改
order.ShipAddress = "昆山軟體外包實訓基地";
order.ShipCity = "China";
// 移除第 3 筆明細
order.Order_Details.RemoveAt(2);
// 修改最後一筆明細
order.Order_Details.Last().Discount = 0.7f;
// 新增兩筆明細
for (int i = 10; i < 12; i++)
{
order.Order_Details.Add(new Order_Details
{
Discount = 0.4f,
Quantity = (short)i,
ProductID = i
});
}
db.SubmitChanges(); // 全部在單一交易完成
}
}


Order_Details 才支援級聯SubmitChanges() 預設隱式交易,可用 TransactionScope 跨 DataContextColumn(IsVersion=true) 或 UpdateCheck 處理樂觀鎖