クエリ射影 (WCF Data Services)
射影は Open Data Protocol (OData) の機能の 1 つであり、エンティティの特定のプロパティのみが応答で返されるように指定することで、クエリによって返されるフィードのデータの量を減らします。 詳細については、OData: Select システム クエリ オプション ($select) の説明を参照してください。
このトピックでは、クエリ射影を定義する方法、エンティティ型、エンティティ型以外の要件、射影された結果に対する更新、射影された型の作成について説明するとともに、射影に関する注意事項をリストします。
クエリ射影の定義
クエリに射影句を追加するには、URI で $select クエリ オプションを使用するか、LINQ クエリで select 句 (Visual Basic の場合は Select) を使用します。 返されたエンティティ データは、クライアント上のエンティティ型またはエンティティ型以外に射影できます。 このトピックでは、LINQ クエリで select 句を使用する例を取り上げます。
注 : |
---|
射影された型に対して行った更新を保存すると、データ サービスでデータの損失が発生する場合があります。詳細については、「Projection Considerations」を参照してください。 |
エンティティ型およびエンティティ型以外の要件
エンティティ型には、エンティティ キーを構成する 1 つ以上の Identity プロパティが必要です。 エンティティ型は、次のいずれかの方法によりクライアントで定義されます。
DataServiceKeyAttribute または DataServiceEntityAttribute を型に適用する。
型に ID という名前のプロパティがある場合。
型に typeID という名前のプロパティがあり、type が型の名前である場合。
既定では、クライアントで定義された型にクエリ結果を射影した場合、射影で要求されたプロパティがクライアント型に存在する必要があります。 ただし、DataServiceContext の IgnoreMissingProperties プロパテに true という値を指定した場合、射影で指定されたプロパティがクライアント型に含まれる必要はありません。
射影された結果に対する更新
クエリ結果をクライアント上のエンティティ型に射影する場合、DataServiceContext はそれらのオブジェクトを追跡し、SaveChanges メソッドが呼び出されるとデータ サービスに更新内容が送り返されます。 ただし、クライアント上のエンティティ型以外に射影されたデータの更新内容は、データ サービスに送り返すことはできません。 これは、エンティティ インスタンスを識別するキーがなければ、データ サービスはデータ ソース内の正しいエンティティを更新できないためです。 エンティティ型以外は DataServiceContext にはアタッチされません。
データ サービスで定義されたエンティティ型の 1 つ以上のプロパティが、エンティティの射影先のクライアント型に含まれない場合、新しいエンティティの挿入には、これらの欠損しているプロパティは含まれません。 この場合、欠損しているこれらのプロパティは既存のエンティティに対する更新にも含まれません。 そのようなプロパティに対する値が存在する場合、データ ソースの定義に従い、更新ではその値がそのプロパティの既定値としてリセットされます。
射影型の作成
次の例では、Customers 型のアドレス関連のプロパティを、クライアントで定義されエンティティ型として属性化された新しい CustomerAddress 型に射影する匿名の LINQ クエリを使用します。
' 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 エンティティ型のインスタンスに射影されます。 匿名型への射影はサポートされていますが、匿名型はエンティティ型以外として扱われるので、データは読み取り専用です。
DataServiceContext の MergeOption 設定は、クエリ射影時の ID 解決に使用されます。 これは、Customer 型のインスタンスが DataServiceContext に存在する場合、同じ ID を持つ CustomerAddress のインスタンスは MergeOption で設定された ID 解決ルールに従うことを意味します。
次の表では、結果をエンティティ型またはエンティティ型以外に射影する場合の動作について説明します。
射影時の注意事項
クエリ射影を定義する場合は、次の点にも注意してください。
Atom 形式のフィードを独自に定義する場合、カスタム マッピングが定義されているすべてのエンティティ プロパティが射影に含まれることを確認する必要があります。 マップされているエンティティ プロパティが射影に含まれていない場合、データの損失が発生することがあります。 詳細については、「フィードのカスタマイズ (WCF Data Services)」を参照してください。
データ サービスのデータ モデルのエンティティのすべてのプロパティを含まない射影型に挿入を行った場合、クライアントで射影に含まれていないプロパティは既定値に設定されます。
データ サービスのデータ モデルのエンティティのすべてのプロパティを含まない射影影型に対して更新を行った場合、クライアントで射影に含まれていない既存の値は初期化されていない既定値で上書きされます。
射影に複合プロパティが含まれる場合、複合オブジェクト全体が返される必要があります。
射影にナビゲーション プロパティが含まれる場合、Expand メソッドを呼び出す必要はなく、関連オブジェクトが暗黙的に読み込まれます。 射影されたクエリでの Expand メソッドの使用はサポートされません。
クライアント上のクエリ射影クエリは、要求 URI の $select クエリ オプションを使用するように変換されます。 $select クエリ オプションをサポートしない WCF Data Services の以前のバージョンに対して、射影のあるクエリを実行すると、エラーが返されます。 これは、データ サービスの DataServiceBehavior の MaxProtocolVersion が V1 という値に設定されている場合にも発生します。 詳細については、「WCF Data Services の複数のバージョンの使用」を参照してください。
詳細については、「方法: クエリ結果を射影する (WCF Data Services)」を参照してください。