// ------------------------------------------------------------
// Join:透過 CategoryId 將 Products 和 Categories 資料表進行關聯查詢
LabDbEntities context = new LabDbEntities(); // 建立資料庫上下文
var query = from p in context.Products
join c in context.Categories on p.CategoryId equals c.CategoryId // 透過 CategoryId 進行內部連接(Join)
select new {
CategoryName = c.CategoryName, // 選擇分類名稱
ProductName = p.ProductName, // 選擇產品名稱
UnitsInStock = p.UnitsInStock // 選擇產品庫存數量
};
dataGridView1.DataSource = query.ToList(); // 將查詢結果綁定到 DataGridView 以便顯示
// ------------------------------------------------------------
// Navigation Properties:透過導航屬性取得關聯資料
LabDbEntities context = new LabDbEntities(); // 建立資料庫上下文
Product obj = context.Products.Find(2); // 使用 Find 方法找到 ProductId 為 2 的產品
Category c = obj.Category; // 使用導航屬性直接存取與該產品關聯的 Category 物件
button1.Text = c.CategoryName; // 將分類名稱顯示在按鈕上
// ------------------------------------------------------------
// Concurrency Model:處理多使用者同時修改數據的情況
try {
db.SaveChanges(); // 嘗試保存變更
}
catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex) {
// 當發生並發衝突時捕獲異常
LabDbEntities db2 = new LabDbEntities(); // 建立另一個上下文來重新取得資料
Product p = db2.Products.Find(2); // 取得 ProductId 為 2 的產品
p.UnitsInStock -= 20; // 減少庫存
db2.SaveChanges(); // 保存變更
}
// ------------------------------------------------------------
// Multi-User Lab:模擬多使用者同時修改庫存數據的情境
// 初始化表單時,採用讀取未提交 (Read Uncommitted) 隔離層級進行查詢
public Form1() {
InitializeComponent();
LabDbEntities context = new LabDbEntities(); // 建立資料庫上下文
var t = context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted); // 開啟事務,使用 Read Uncommitted 隔離層級
Product obj = context.Products.Find(2); // 查詢 ProductId 為 2 的產品
t.Commit(); // 提交事務
label1.Text = obj.UnitsInStock.ToString(); // 顯示庫存數量
}
// 按下購買按鈕時,模擬減少庫存的操作
private void BuyButton_Click(object sender, EventArgs e) {
LabDbEntities context = new LabDbEntities(); // 建立資料庫上下文
Product obj = context.Products.Find(2); // 查詢 ProductId 為 2 的產品
obj.UnitsInStock -= 1; // 將庫存減少 1
System.Threading.Thread.Sleep(1000 * 10); // 模擬延遲,模擬多使用者同時操作情境
context.SaveChanges(); // 保存變更
(sender as Button).Text = "Done"; // 按鈕顯示完成
}
// 按下另一個購買按鈕時,模擬使用 SQL 查詢來鎖定資料
private void BuyButtonV2_Click(object sender, EventArgs e) {
LabDbEntities context = new LabDbEntities(); // 建立資料庫上下文
var t = context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted); // 使用 Read Uncommitted 隔離層級開啟事務
Product obj = context.Products.SqlQuery("select * from products with (xlock) where productId = 2").FirstOrDefault();
// 使用 SQL 查詢並鎖定 ProductId 為 2 的資料行,防止其他用戶同時更新
obj.UnitsInStock -= 1; // 減少庫存
context.SaveChanges(); // 保存變更
System.Threading.Thread.Sleep(1000 * 10); // 模擬延遲
t.Commit(); // 提交事務
}
join
語法在兩個資料表之間進行聯結,並根據外鍵(如 CategoryId
)取得相關資料。Product
查詢 Category
)。這些註釋讓每個功能點都能夠清晰展示,幫助學生理解各個功能在實際開發中的應用。
補充:XML
System.Xml.
System.Xml.XmlWriter