首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

VS 2008 SP1 + .NET 3.5 SP1 (5) - Entity Framework ObjectContext 與交易併發

     編輯:關於.NET

ObjectContext 核心操作

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 / Attach)

// 方式一: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 與實體查詢

EntityKey ek = ctx.CreateEntityKey("Region", new Region { RegionID = 100 });
Region r = ctx.GetObjectByKey(ek) as Region; // 從上下文或資料庫取得

交易處理

同一 ObjectContext 多次 SaveChanges 交易

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

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved