When you use the Add Service Reference dialog to consume an Open Data Protocol (OData) feed in a .NET Framework-based client application, equivalent data classes are generated for each entity type in the data model exposed by the feed. For more information, see Generating the Data Service Client Library. Entity data that is returned by a query is materialized into an instance of one of these generated client data service classes. For information about merge options and identity resolution for tracked objects, see Managing the Data Service Context.
WCF Data Services also enables you to define your own client data service classes rather than using the tool-generated data classes. This enables you to use your own data classes, also known as "plain-old CLR object" (POCO) data classes. When using these types of custom data classes, you should attribute the data class with either DataServiceKeyAttribute or DataServiceEntityAttribute and ensure that type names on the client match type names in the data model of the data service.
After the library receives the query response message, it materializes the returned data from the OData feed into instances of client data service classes that are of the type of the query. The general process for materializing these objects is as follows:
The client library reads the serialized type from the
entryelement in the response message feed and attempts to create a new instance of the correct type, in one of the following ways:
When the type declared in the feed has the same name as the type of the DataServiceQuery<TElement>, a new instance of this type is created by using the empty constructor.
When the type declared in the feed has the same name as a type that is derived from the type of the DataServiceQuery<TElement>, a new instance of this derived type is created by using the empty constructor.
When the type declared in the feed cannot be matched to the type of the DataServiceQuery<TElement> or any derived types, a new instance of the queried type is created by using the empty constructor.
When the ResolveType property is set, the supplied delegate is called to override the default name-based type mapping and a new instance of the type returned by the Func<T,TResult> is created instead. If this delegate returns a null value, a new instance of the queried type is created instead. It may be required to override the default name-based type name mapping to support inheritance scenarios.
The client library reads the URI value from the
idelement of the
entry, which is the identity value of the entity. Unless a MergeOption value of NoTracking is used, the identity value is used to track the object in the DataServiceContext. The identity value is also used to guarantee that only a single entity instance is created, even when an entity is returned multiple times in the query response.
The client library reads properties from the feed entry and set the corresponding properties on the newly created object. When an object that has the same identity value already occurs in the DataServiceContext, the properties are set based on the MergeOption setting of the DataServiceContext. The response might contain property values for which a corresponding property does not occur in the client type. When this occurs, the action depends on the value of the IgnoreMissingProperties property of the DataServiceContext. When this property is set to
true, the missing property is ignored. Otherwise, an error is raised. Properties are set as follows:
Scalar properties are set to the corresponding value in the entry in the response message.
Complex properties are set to a new complex type instance, which are set with the properties of the complex type from the response.
Navigation properties that return a collection of related entities are set to a new or existing instance of ICollection<T>, where
Tis the type of the related entity. This collection is empty unless the related objects have been loaded into the DataServiceContext. For more information, see Loading Deferred Content.
The ReadingEntity event is raised.