共用方式為


查詢投影 (WCF 資料服務)

投影會在 Open Data Protocol (OData) 中提供一種機制,可藉由指定回應中僅傳回特定實體屬性的方式,減少查詢傳回之摘要中的資料量。 如需詳細資訊,請參閱 OData:Select 系統查詢選項 ($select) (英文)。

本主題描述如何定義查詢投影、實體與非實體類型的需求為何、對投影結果進行更新、建立投影類型,以及列出一些投影考量因素。

定義查詢投影

您可以將投影子句加入查詢中,方式為在 URI 中使用 $select 查詢選項或在 LINQ 查詢中使用 select 子句 (在 Visual Basic 中為 Select)。 傳回的實體資料可以投影至用戶端上的實體類型或非實體類型。 此主題中的範例將示範如何在 LINQ 查詢中使用 select 子句。

Ee473425.Important(zh-tw,VS.100).gif 注意:
當您儲存對投影類型所進行的更新時,資料服務中可能會發生資料遺失。 如需詳細資訊,請參閱Projection Considerations。

實體與非實體類型的需求

實體類型必須具備一個或多個構成實體索引鍵的識別屬性。 實體類型在用戶端上是利用下列其中一種方式來定義:

根據預設,當您將查詢結果投影至用戶端上定義的類型時,投影中要求的屬性必須是用戶端上現有的類型。 但是,當您為 DataServiceContextIgnoreMissingProperties 屬性指定 true 值時,投影中指定的屬性就不一定要用戶端上現有的類型。

對投影結果進行更新

若已呼叫 SaveChanges 方法,當您將查詢結果投影至用戶端上的實體類型時,DataServiceContext 可以使用要傳送回資料服務的更新來追蹤該些物件。 但是,對投影至用戶端上之非實體類型的資料所進行之更新,無法傳送回資料服務。 這是因為沒有索引鍵可識別實體執行個體,資料服務無法更新資料來源中的正確實體。 非實體類型並未附加至 DataServiceContext

當資料服務中所定義之實體類型的一個或多個屬性並不存在實體所投影至的用戶端類型中時,插入新的實體並不會包含這些遺漏的屬性。 在這種情況下,對現有實體進行的更新不會包括這些遺漏的屬性。 若此類屬性中已存有值,更新會依資料來源中所定義,將它重設為屬性的預設值。

建立投影類型

下列範例使用匿名 LINQ 查詢,將 Customers 類型的地址相關屬性投影至新的 CustomerAddress 類型,後者類型已在用戶端上定義並屬性化為實體類型:

' Define an anonymous LINQ query that projects the Customers type into 
' a CustomerAddress type that contains only address properties.
Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With { _
                    .CustomerID = c.CustomerID, _
                    .Address = c.Address, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
// Define an anonymous LINQ query that projects the Customers type into 
// a CustomerAddress type that contains only address properties.
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress { 
                CustomerID = c.CustomerID, 
                Address = c.Address, 
                City = c.City, 
                Region = c.Region,
                PostalCode = c.PostalCode, 
                Country = c.Country};

在此範例中,物件初始設定式模式會用來建立 CustmerAddress 類型的新執行個體,而非用來呼叫建構函式。 在投影至實體類型時不支援建構函式,但是投影至非實體與匿名類型時可以使用建構函式。 因為 CustomerAddress 是實體類型,所以可以進行變更並將變更傳送回資料服務。

而且,取自 Customer 類型的資料是投影至 CustomerAddress 實體類型的執行個體,而非投影至匿名類型。 可支援投影至匿名類型,但是因為匿名類型被視為非實體類型,所以資料是唯讀的。

DataServiceContextMergeOption 設定可在查詢投影期間供識別解析使用。 這表示如果 DataServiceContext 中已有 Customer 類型的執行個體,使用相同識別之 CustomerAddress 的執行個體將會依照 MergeOption 所設定的識別解析規則

下表描述將結果投影至實體與非實體類型時的行為:

動作 實體類型 非實體類型

使用初始設定式建立新的投影執行個體,如下列範例所示:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With { _
                    .CustomerID = c.CustomerID, _
                    .Address = c.Address, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress { 
                CustomerID = c.CustomerID, 
                Address = c.Address, 
                City = c.City, 
                Region = c.Region,
                PostalCode = c.PostalCode, 
                Country = c.Country};

支援

支援

使用建構函式建立新的投影執行個體,如下列範例所示:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress( _
                c.CustomerID, _
                c.Address, _
                c.City, _
                c.Region, _
                c.PostalCode, _
                c.Country)
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress(
            c.CustomerID, 
            c.Address, 
            c.City, 
            c.Region,
            c.PostalCode, 
            c.Country);

引發 NotSupportedException

支援

使用投影來轉換屬性值,如下列範例所示:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With _
                {.CustomerID = c.CustomerID, _
                    .Address = "Full address: " & c.Address & ", " & _
                    c.City & "," & c.Region & " " & c.PostalCode, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress
            {
                CustomerID = c.CustomerID, 
                Address = "Full address:" + c.Address + ", " +
                c.City + ", " + c.Region + " " + c.PostalCode,
                City = c.City,
                Region = c.Region,
                PostalCode = c.PostalCode,
                Country = c.Country
            };

實體類型不支援此種轉換,因為它可能造成混淆且可能覆寫屬於另一個實體之資料來源中的資料。

引發 NotSupportedException

支援

投影考量因素

下列其他考量因素適用於定義查詢投影時。

  • 在定義 Atom 格式的自訂摘要時,您必須確保所有已定義自訂對應的實體屬性都包含在投影中。 若投影中未包含對應的實體屬性,則可能會發生資料遺失。 如需詳細資訊,請參閱摘要自訂 (WCF Data Services)

  • 對未包含資料服務之資料模型中的所有實體屬性之投影類型進行插入時,用戶端上未包含在投影內的屬性會設定為它們的預設值。

  • 對未包含資料服務之資料模型中的所有實體屬性之投影類型進行更新時,用戶端上未包含在投影內的現有值將被覆寫成未初始化的預設值。

  • 當投影包括一種複雜屬性時,必須傳回整個複雜物件。

  • 當投影包含導覽屬性時,相關物件會以隱含方式載入,不必呼叫 Expand 方法。 不支援將 Expand 方法用於投影查詢中。

  • 查詢用戶端上的投影查詢會轉譯為在要求 URI 中使用 $select 查詢選項。 若針對舊版 WCF Data Services 執行使用投影的查詢 (該版本不支援 $select 查詢選項),會傳回錯誤。 在將資料服務之 DataServiceBehaviorMaxProtocolVersion 設定為 V1 值時也會發生這種情況。 如需詳細資訊,請參閱使用 WCF Data Services 的多個版本

如需詳細資訊,請參閱 HOW TO:專案查詢結果 (WCF Data Services)

另請參閱

概念

查詢資料服務 (WCF Data Services)