Object Materialization (WCF Data Services)

Important

WCF Data Services has been deprecated and will no longer be available for download from the Microsoft Download Center. WCF Data Services supported earlier versions of the Microsoft OData (V1-V3) protocol only and has not been under active development. OData V1-V3 has been superseded by OData V4, which is an industry standard published by OASIS and ratified by ISO. OData V4 is supported through the OData V4 compliant core libraries available at Microsoft.OData.Core. Support documentation is available at OData.Net, and the OData V4 service libraries are available at Microsoft.AspNetCore.OData.

RESTier is the successor to WCF Data Services. RESTier helps you bootstrap a standardized, queryable, HTTP-based REST interface in minutes. Like WCF Data Services before it, Restier provides simple and straightforward ways to shape queries and intercept submissions before and after they hit the database. And like Web API + OData, you still have the flexibility to add your own custom queries and actions with techniques you're already familiar with.

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:

  1. The client library reads the serialized type from the entry element 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.

  2. The client library reads the URI value from the id element 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.

  3. 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 T is 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.

      Note

      When the generated client data classes support data binding, navigation properties return instances of the DataServiceCollection<T> class instead. For more information, see Binding Data to Controls.

  4. The ReadingEntity event is raised.

  5. The client library attaches the object to the DataServiceContext. The object is not attached when the MergeOption is NoTracking.

See also