共用方式為


管理資料服務內容 (WCF Data Services)

DataServiceContext 類別會封裝針對特定資料服務支援的作業。 雖然 OData 服務沒有狀態,但是內容具有狀態。 因此,您可以使用 DataServiceContext 類別,在用戶端上維護與資料服務互動之間的狀態,以便支援變更管理之類的功能。 這個類別也可以管理識別及追蹤變更。

合併選項和識別解析

當執行 DataServiceQuery<TElement> 時,回應摘要中的實體會具體化成為物件。 如需詳細資訊,請參閱物件具體化 (WCF Data Services)。 回應訊息中的項目具體化成為物件的方式是根據識別解析來執行,而且會取決於執行查詢時所使用的合併選項。 如果在單一 DataServiceContext 的範圍中執行多個查詢或載入要求,則 WCF Data Services 用戶端只會追蹤具有特定索引鍵值之物件的單一執行個體。 用來執行識別解析的這個索引鍵會唯一識別實體。

根據預設,用戶端只會將回應摘要中的項目具體化成為實體的物件,而這些實體尚未被 DataServiceContext 所追蹤。 這表示,已經在快取中之物件的變更不會遭到覆寫。 這個行為的控制方式,是針對查詢和載入作業指定 MergeOption 值。 這個選項的指定方式是在 DataServiceContext 上設定 MergeOption 屬性。 預設的合併選項值是 AppendOnly。 這樣只會具體化尚未被追蹤之實體的物件,這表示現有的物件不會遭到覆寫。 有另一個方式可避免用戶端的物件變更遭到資料服務中的更新所覆寫,就是指定 PreserveChanges。 當您指定 OverwriteChanges 時,將會使用回應摘要中項目的最新值來取代用戶端的物件值,即使這些物件已有變更亦然。 當使用 NoTracking 合併選項時,DataServiceContext 無法將用戶端物件所做的變更傳送給資料服務。 使用這個選項時,一定會使用資料服務中的值來覆寫變更。

管理並行存取

OData 支援可讓資料服務偵測更新衝突的開放式並行存取。 可以透過一種方式來設定資料服務提供者,讓資料服務使用並行語彙基元來檢查實體的變更。 這個語彙基元包含實體類型的一個或多個屬性,資料服務會驗證這些屬性以判斷資源是否已變更。 WCF Data Services 用戶端會為您管理並行語彙基元 (包含在與資料服務之間的要求與回應的 eTag 標頭中)。如需詳細資訊,請參閱更新資料服務 (WCF Data Services)

DataServiceContext 會追蹤使用 AddObjectUpdateObjectDeleteObject 或是 DataServiceCollection<T> 所手動提報的物件變更。 當呼叫 SaveChanges 方法時,用戶端會將變更傳回資料服務。 當用戶端的資料變更與資料服務的變更衝突時,SaveChanges 會失敗。 當發生這個狀況時,您必須再次查詢實體資源,以接收更新資料。 若要覆寫資料服務中的變更,請使用 PreserveChanges 合併選項執行查詢。 當您再次呼叫 SaveChanges 時,用戶端所保留的變更會保存到資料服務,前提是尚未針對資料服務中的資源進行其他變更。

儲存變更

變更會在 DataServiceContext 執行個體中追蹤,但是不會立即傳送至伺服器。 在針對指定的活動完成所需的變更之後,請呼叫 SaveChanges,將所有變更提交至資料服務。 SaveChanges 作業完成後,會傳回 DataServiceResponse 物件。 DataServiceResponse 物件包含一連串的 OperationResponse 物件,其中依序包含一連串的 EntityDescriptorLinkDescriptor 執行個體,表示持續性或嘗試性的變更。 在資料服務中建立或修改實體時,EntityDescriptor 會包括已更新實體的參考,其中包含任何伺服器產生的屬性值,例如以上範例中產生的 ProductID 值。 用戶端程式庫會自動更新 .NET Framework 物件以便擁有這些新值。

對於成功插入和更新的作業,與作業相關聯的 EntityDescriptorLinkDescriptor 物件之狀態屬性會設定為 Unchanged,而新值則是使用 OverwriteChanges 來合併。

當資料服務中的插入、更新或刪除作業失敗時,實體狀態會維持不變,與呼叫 SaveChanges 之前相同,而且 OperationResponseError 屬性會設定為 DataServiceRequestException,其中包含與該錯誤有關的資訊。 如需詳細資訊,請參閱更新資料服務 (WCF Data Services)

管理要求

OData 通訊協定在資料服務接收要求與發出回應的行為中提供靈活性。 用戶端程式庫可讓您透過控制應用程式與資料服務互動的方式,善用這種靈活性。

設定變更作業的 Prefer 標頭

根據預設,只有在回應要建立新實體的 POST 要求時才會傳回訊息裝載。 在此情況下,新實體會在裝載中傳回。 這表示對物件進行更新時,不會在裝載或回應訊息中傳回更新的實體。 然而,OData 通訊協定規定用戶端可以使用 Prefer 標頭來要求變更此預設行為。 POST、PUT、PATCH 或 MERGE 要求中的 Prefer 標頭是由 DataServiceContext 根據 AddAndUpdateResponsePreference 屬性中設定的 DataServiceResponsePreference 值所產生。 下表顯示 Prefer 標頭選項和相關的回應行為:

Prefer 標頭值

AddAndUpdateResponsePreference

回應行為

不包含在要求中。 這是預設行為。

None

回應裝載僅對 POST 要求傳回,對 PUT、PATCH 和 MERGE 要求則不傳回。

return-content

IncludeContent

回應裝載會為所有變更要求傳回。

return-no-content

NoContent

回應裝載不對任何要求傳回。 對於 POST 要求,資料服務還會將 DataServiceId 標頭包含回應中。 此標頭用於傳送新建立實體的索引鍵值。

注意

甚至當資料服務支援的 OData 通訊協定版本支援 Prefer 標頭時,資料服務仍可選擇不接受這些類型的要求處理偏好設定。

設定更新的 HTTP 方法

.NET Framework 用戶端程式庫預設會將更新當做 MERGE 要求,傳送到現有的實體。 在 OData 中,MERGE 要求會更新選取的實體屬性,但是用戶端永遠會將所有屬性包含在 MERGE 要求中,即使屬性並未變更也是如此。 OData 通訊協定還支援將 PUT 和 PATCH 要求傳送至更新實體。 在 PUT 要求中,現有的實體基本上會從用戶端取代成具有屬性值的新實體執行個體。 處理 PATCH 要求的方式與處理 MERGE 要求的方式相同,但是 PATCH 要求是標準的 HTTP 動作,而 MERGE 則是由 OData 所定義。 指定這種更新行為的方式是在呼叫 SaveChanges(SaveChangesOptions) 時,提供 ReplaceOnUpdate 值以使用 PUT 要求當做選項,或提供 PatchOnUpdate 值以使用 PATCH 要求當做選項。

注意

當用戶端並不完全知道實體的所有屬性時,PUT 要求的行為與 MERGE 或 PATCH 要求的行為會有所不同。將實體型別投影到用戶端上的新型別時,可能會發生這個情況。將新屬性加入至服務資料模型中的實體,而且 DataServiceContext 上的 IgnoreMissingProperties 屬性設為 true 來忽略此類用戶端對應錯誤時,也可能會發生這個情況。在這些情況下,PUT 要求會將用戶端不知道的任何屬性重設為其預設值。

POST 通道

預設情況下,用戶端程式庫會使用 POST、GET、PUT/MERGE/PATCH 和 DELETE 的對應 HTTP 方法,將建立、讀取、更新和刪除要求傳送給 OData 服務。 這樣做表示支持代表性狀態傳輸 (Representational State Transfer,REST) 的基本原則。 不過,並不是所有 Web 伺服器實作都會支援完整的 HTTP 方法集。 在某些情況下,支援的方法可能僅限於 GET 和 POST。 像防火牆這樣的媒介透過某些方法阻擋要求時,就可能發生這種情況。 由於 GET 和 POST 方法最常受到支援,OData 會使用 POST 要求來描述執行所有不受支援 HTTP 方法的執行方式。 這種方式稱為「方法通道」(Method Tunneling) 或「POST 通道」(POST Tunneling),可讓用戶端以自訂 X-HTTP-Method 標頭中指定的實際方法來傳送 POST 要求。 若要啟用 POST 通道以傳送要求,請將 DataServiceContext 執行個體上的 UsePostTunneling 屬性設定為 true。

解析實體集的基底 URI

預設情況下,用戶端假設所有實體集 (也稱為集合) 都共用相同的基底 URI。 這個基底 URI 是由 DataServiceContext 中的 BaseUri 屬性所定義。 但是 OData 通訊協定允許資料服務將實體集公開為基底 URI 不同的摘要。 為了能以不同的基底 URI 處理實體集,用戶端允許您向可用於解析各種實體集之基底 URI 的 DataServiceContext 註冊委派。 這個委派是一個會接受字串 (實體集名稱) 和傳回 Uri (指定之實體集的基底 URI) 的方法。 這個解析程式透過指派 ResolveEntitySet 屬性的方式向 DataServiceContext 註冊。 建立內容時,範例解析程式實作可能會讀取資料服務根目錄傳回的集合相關資訊,並將每個集合的基底 URI 值儲存在字典中。 然後解析程式就可以使用這個詞典傳回特定實體集的 URI。 如需包含範例程式碼的更完整範例,請參閱文章實體集解析程式

版本控制需求

DataServiceContext 行為有下列 OData 通訊協定版本控制需求:

  • 對 Prefer 標頭和 PATCH 要求的支援需要用戶端和資料服務都支援 OData 通訊協定 3.0 版 (含) 以後版本。

  • 對實體集解析程式的支援需要 Data Framework 發行版 (含) 以後版本隨附的 WCF Data Services 用戶端程式庫版本。

如需詳細資訊,請參閱資料服務版本控制 (WCF Data Services)