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

Linq to SQL 物件身分識別機制深度解析:主鍵、快取與屬性追蹤

     編輯:關於.NET

核心概念:物件身分識別

在同一 DataContext 執行個體中,**主鍵相同的實體物件只會存在一份** (Identity Cache)。無論查詢多少次,回傳皆為同一參考。

驗證範例

// 實體查詢:主鍵相同 → 同一物件
var c1 = db.Categories.Single(o => o.CategoryId == 1);
var c2 = db.Categories.Single(o => o.CategoryId == 1);
Console.WriteLine(c1 == c2); // True

// 匿名型別投影:無主鍵 → 每次新物件
var a1 = db.Categories.Select(o => new { o.CategoryId, o.CategoryName })
                      .Single(o => o.CategoryId == 1);
var a2 = db.Categories.Select(o => new { o.CategoryId, o.CategoryName })
                      .Single(o => o.CategoryId == 1);
Console.WriteLine(a1 == a2); // False

為何匿名型別不支援身分識別?

  • 匿名型別無固定主鍵,Linq to SQL 無法建立快取索引鍵。
  • 每次查詢皆重新實例化,屬於值語義而非參考語義。

資料庫外部修改後的快取行為

  1. 查詢 CategoryId=1 → CategoryName="Beverages",物件進入快取。
  2. 直接在資料庫將該筆改為 "New Name"。
  3. 同一 DataContext 再次查詢 CategoryId=1 → 回傳**快取中舊物件**,CategoryName 仍為 "Beverages"。
資料庫修改截圖

強制重新載入:Refresh 方法

db.Refresh(RefreshMode.OverwriteCurrentValues, c2);
// 或 RefreshMode.KeepCurrentValues (保留本地修改,合併伺服器值)

執行後 c2.CategoryName 更新為 "New Name"。

屬性變更追蹤機制

方式一:實作 INotifyPropertyChanged (推薦)

實體類別實作介面,Setter 中呼叫 SendPropertyChanged("PropertyName"),Linq to SQL 透過事件即時得知變更,SubmitChanges 只產生必要 UPDATE SQL。

public string CategoryName {
    get { return _CategoryName; }
    set {
        if (_CategoryName != value) {
            OnPropertyChanging("CategoryName");
            _CategoryName = value;
            OnPropertyChanged("CategoryName");
        }
    }
}

方式二:不實作介面 → 比對快照

DataContext 載入實體時建立淺層複製快照。SubmitChanges 時比對目前值與快照值,不同者納入 UPDATE。
缺點:若實體類別實作了 INotifyPropertyChanged 但 Setter **未觸發事件** (如直接賦值 _CategoryName = value),Linq to SQL 會誤判為未變更,**不產生 UPDATE SQL**,導致資料不同步。

主鍵不可變鐵律

因身分識別依賴主鍵,**主鍵值一旦載入不可修改**。嘗試修改主鍵會導致快取索引錯亂、關聯關係破壞。

總結

特性實體類別 (有主鍵)匿名型別
身分識別快取是 (依主鍵)否
支援 Insert/Update/Delete是否
屬性追蹤INotifyPropertyChanged / 快照比對不適用
跨查詢參考一致性保證不保證

掌握身分識別、快取、追蹤三大機制,才能正確使用 Linq to SQL 避免資料不一致、效能浪費與更新遺漏等陷阱。

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