Share via


Object Materialization (ADO.NET Data Services)

When you use the Add Service Reference dialog to add a data service to a .NET Framework-based client application, equivalent data classes are generated for each entity type that can be accessed by using the ADO.NET Data Services. For more information, see Generating the Data Service Client Library (ADO.NET Data Services). When you use these generated client data classes, entity data that is returned by a query is materialized into an instance of one of these generated client data service classes.

ADO.NET 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. The client library runtime can also infer the correct data type from the name of the identity property.

After the library receives the query response message, it materializes the returned data 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, a new instance of this type is created by using the default constructor.

    • When the type declared in the feed has the same name as a type that is derived from the type of the DataServiceQuery, a new instance of this derived type is created by using the default constructor.

    • When the type declared in the feed cannot be matched to the type of the DataServiceQuery or any derived types, a new instance of the queried type is created by using the default 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 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, 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 (ADO.NET Data Services).

      Note

      When the generated client data classes support data binding, navigation properties instead return instances of the DataServiceCollection class. For more information, see Binding Data to Controls (ADO.NET Data Services).

  4. The client library attaches the object to the DataServiceContext and raises the ReadingEntity() event. The object is not attached when the MergeOption is NoTracking().

See Also

Other Resources

Querying the Data Service (ADO.NET Data Services)

Query Projections (ADO.NET Data Services)