Share via


識別解析、狀態管理和變更追蹤

ObjectContext 表示記憶體中物件的容器。 物件內容藉助其他類別和介面可管理物件的識別、狀態、物件屬性的原始值和目前值,以及追蹤對快取中之每個物件所做的變更。 如需如何將物件附加至物件內容的詳細資訊,請參閱附加及中斷連結物件。 本主題將討論物件內容如何管理變更追蹤、識別解析和狀態管理。

變更追蹤

物件圖形的變更追蹤資訊會儲存在 ObjectStateEntry 物件中,而這些物件是由每個附加物件的 ObjectContext 所建立。ObjectStateEntry 物件會儲存實體的下列資訊:

若要了解某個屬性的值是否已經在 SaveChanges 的呼叫之間變更,請查詢 GetModifiedProperties 方法所傳回之已變更屬性名稱的集合。

Bb896269.note(zh-tw,VS.100).gif注意:
如果您要使用沒有變更追蹤 Proxy 的 POCO 實體,就必須先呼叫 DetectChanges,然後再呼叫 GetModifiedProperties

當實體中斷連結時,系統就會從物件內容中移除對應的 ObjectStateEntry 物件。

ObjectStateEntry 物件是由 ObjectStateManager 管理。 每個物件內容都有一個 ObjectStateManager 的執行個體。 若要取得指定之實體的 ObjectStateEntry 物件,請在 ObjectStateManager上使用下列其中一個方法:TryGetObjectStateEntryGetObjectStateEntryGetObjectStateEntries

發生變更時,物件內容就會收到 Entity Framework 產生實體和 POCO 變更追蹤 Proxy 物件之屬性變更的相關通知,而且它會在 ObjectStateEntry 中更新物件的狀態和屬性的值。 變更報告模型包含報告屬性的暫止變更、設定屬性,然後使用 IEntityChangeTracker 介面來報告變更完成。 ObjectStateEntry 會以不同的方式管理沒有變更追蹤 Proxy 物件的 POCO 實體和複雜型別物件。 如需詳細資訊,請參閱追蹤 POCO 實體中的變更 (Entity Framework)

物件內容會使用 ObjectStateEntry 物件中的資訊,將資料保存到資料來源。 如需詳細資訊,請參閱儲存變更及管理並行存取 (Entity Framework)HOW TO:在儲存變更時執行商務邏輯 (Entity Framework)

識別解析和合併選項

Entity Framework 只會維護快取中具有特定實體索引鍵之物件的單一執行個體。 EntityKey 物件是不可變的物件,代表物件的識別。 實體索引鍵是用來執行物件內容中的識別解析。 如需詳細資訊,請參閱使用實體索引鍵 (Entity Framework)。 如果已追踨具有相同識別的實體,則取自資料來源的資料和狀態管理員中已有的資料就會根據查詢的 MergeOption 進行合併。 

下表顯示可能的合併選項:

成員 說明

AppendOnly

不存在物件內容中的物件會附加至內容。 如果某個物件已經存在內容中,就不會使用資料來源值來覆寫項目中物件屬性的目前和原始值。 物件項目的狀態和項目中物件屬性的狀態不會變更。AppendOnly 是預設合併選項。

OverwriteChanges

不存在物件內容中的物件會附加至內容。 如果某個物件已經存在內容中,就會使用資料來源值來覆寫項目中物件屬性的目前和原始值。 物件項目的狀態會設定為 Unchanged,而且沒有屬性會標示為已修改。

PreserveChanges

不存在物件內容中的物件會附加至內容。

如果實體的狀態為 Unchanged,就會使用資料來源值來覆寫項目中的目前和原始值。 實體的狀態會維持 Unchanged,而且沒有屬性會標示為已修改。

如果實體的狀態為 Modified,就不會使用資料來源值來覆寫已修改屬性的目前值。 不過,系統會使用資料來源的值來覆寫未修改屬性的原始值。

在 .NET Framework 4 版中,Entity Framework 會比較未修改屬性的目前值與資料來源傳回的值。 如果這些值不同,屬性就會標示為已修改。

在 .NET Framework 3.5 SP1 版中,Entity Framework 不會將屬性標示為已修改,即使資料來源中的值不同也一樣。

當您呼叫 SaveChanges 時,只有已修改的屬性會保存到資料來源。

若要保留 3.5 SP1 的行為,請將 UseLegacyPreserveChangesBehavior 設定為 truePreserveChanges 選項可用來解決開放式並行存取例外狀況,同時保留本機內容中的變更。 如需詳細資訊,請參閱儲存變更及管理並行存取 (Entity Framework)

NoTracking

物件會保持處於 Detached 狀態中,而且不會在 ObjectStateManager 中追蹤。 但是,Entity Framework 產生的實體和具有 Proxy 的 POCO 實體會保持物件內容的參考,使相關物件的載入更容易。

實體狀態

物件內容必須了解物件狀態,才能將變更儲存回資料來源。ObjectStateEntry 物件會儲存 EntityState 資訊。 ObjectContextSaveChanges 方法會處理附加至內容的實體,並根據每個物件的 EntityState 來更新資料來源。 如需詳細資訊,請參閱建立、加入、修改和刪除物件。 下表顯示物件的可能狀態:

成員 說明

Added

物件是新的、已經加入至物件內容,而且尚未呼叫 SaveChanges 方法。 儲存變更之後,物件狀態會變更為 Unchanged。 處於 Added 狀態的物件在 ObjectStateEntry 中沒有原始值。

Deleted

已經從物件內容中刪除物件。 儲存變更之後,物件狀態會變更為 Detached

Detached

此物件存在,但是沒有追蹤此物件。 在已經建立實體之後而在實體加入至物件內容之前,實體就會處於這種狀態中。 在已經透過呼叫 Detach 方法從內容中移除實體後,或是使用 NoTracking MergeOption 載入實體的話,實體也會處於這種狀態中。 沒有任何 ObjectStateEntry 執行個體會與處於 Detached 狀態的物件相關聯。

Modified

物件上的其中一個純量屬性已修改,而且尚未呼叫 SaveChanges 方法。 已呼叫 DetectChanges 方法時,在沒有變更追蹤 Proxy 的 POCO 實體中,已修改之屬性的狀態會變更為 Modified。 儲存變更之後,物件狀態會變更為 Unchanged

Unchanged

自從此物件附加至內容,或者自從上一次呼叫 SaveChanges 方法以來,此物件就沒有修改過。

物件內容內部的物件狀態是由 ObjectStateManager 所管理的。 若要找出物件狀態,請呼叫下列其中一個 ObjectStateManager 方法:TryGetObjectStateEntryGetObjectStateEntryGetObjectStateEntriesObjectStateEntryState 屬性會定義物件的狀態。

另請參閱

概念

使用實體索引鍵 (Entity Framework)