ObjectContext 是 Entity Framework 中以物件形式操作資料的核心類別,管理實體狀態、變更追蹤與資料庫同步。
using (var ctx = new NorthwindEntities()) {
// 1. 建立新實體 (Detached)
Region region = Region.CreateRegion("RegionDescription", 100);
// EntityState.Detached
// 2. 加入上下文 (Added)
ctx.AddToRegion(region); // 或 ctx.AddObject("Region", region)
// EntityState.Added
// 3. 儲存變更 (Unchanged)
ctx.SaveChanges(); // 或 SaveChanges(false) 保留狀態
// EntityState.Unchanged
// 4. 修改實體 (Modified)
region.RegionDescription = "Updated";
// EntityState.Modified
// 5. 刪除實體 (Deleted)
ctx.DeleteObject(region); // 或 ObjectStateEntry.Delete()
// EntityState.Deleted
}
ObjectStateEntry ose = ctx.ObjectStateManager.GetObjectStateEntry(region);
ose.State; // 目前狀態
ose.OriginalValues["RegionDescription"]; // 原始值
ose.CurrentValues["RegionDescription"]; // 目前值
ose.AcceptChanges(); // 標記為 Unchanged
ctx.AcceptAllChanges(); // 所有實體標記為 Unchanged
// 方式一:ApplyPropertyChanges - 需先載入原始實體
Region regionRead = ctx.Region.First(p => p.RegionID == 100);
Region regionUpdate = Region.CreateRegion("NewDesc", 100);
ctx.ApplyPropertyChanges("Region", regionUpdate); // regionRead 變為 Modified
// 方式二:Attach + SetModifiedProperty
Region region = new Region { RegionID = 100, RegionDescription = "NewDesc" };
ctx.AttachTo("Region", region);
ObjectStateEntry ose = ctx.ObjectStateManager.GetObjectStateEntry(region);
ose.SetModifiedProperty("RegionDescription");
ctx.Refresh(RefreshMode.ClientWins, region); // 以用戶端值為準
ctx.SaveChanges();
EntityKey ek = ctx.CreateEntityKey("Region", new Region { RegionID = 100 });
Region r = ctx.GetObjectByKey(ek) as Region; // 從上下文或資料庫取得
using (var ctx = new NorthwindEntities()) {
if (ctx.Connection.State != ConnectionState.Open) ctx.Connection.Open();
DbTransaction tran = ctx.Connection.BeginTransaction();
try {
ctx.AddToRegion(Region.CreateRegion("Test", 101));
ctx.SaveChanges(); // 第一次操作
ctx.AddToRegion(Region.CreateRegion("Test2", 101)); // 主鍵重複會失敗
ctx.SaveChanges(); // 第二次操作
tran.Commit();
} catch {
tran.Rollback(); // 回滾第一次插入
}
}
需在 EDM 將並發模式設為 Fixed 的屬性上啟用。
var ctx = new NorthwindEntities();
var ctx2 = new NorthwindEntities();
var region = ctx.Region.First();
var region2 = ctx2.Region.First();
region.RegionDescription = "Eastern" + Guid.NewGuid();
region2.RegionDescription = "Eastern" + Guid.NewGuid();
ctx.SaveChanges(); // 先寫入成功
try {
ctx2.SaveChanges(); // 拋出 OptimisticConcurrencyException
} catch (OptimisticConcurrencyException) {
// 解決衝突:StoreWins (以資料庫為準) 或 ClientWins (以用戶端為準)
ctx2.Refresh(RefreshMode.StoreWins, region2);
ctx2.SaveChanges();
}
ObjectContext 提供完整的實體生命週期管理,配合 ObjectStateManager 可精細控制變更追蹤。交易與並發處理是企業級應用的關鍵。完整原始碼:https://www.bianceng.net/dotnet/201212/805.htm