What is a derived property?

A derived property is a property that does not exist on the EntityType associated with the EntitySet; rather it exists on a type that derives from the base type of the entity set. This feature has been among our customers top asks since the lack of support makes exposing models with rich, well-defined inheritance hierarchies impossible to do. To enable such scenarios WCF Data Services now supports both exposing and consuming models which have properties (primitive, complex & navigation) defined on subtypes of the base type associated with the set

How can I specify derived properties in CSDL?

As you know, WCF Data Services exposes a metadata document ($metadata endpoint) which describes the data model exposed by the service.  Below is an example of a metadata document that defines derived properties. No new extensions have been added to support this functionality. Protocol changes need to support derived properties can be found here

NavpropsCSDL

How are derived properties used on the client?

A representation of the above example in a .NET type would be:

public class Person

{

    public int ID { get; set; }

public string FirstName{ get; set; }

public string LastName{ get; set; }

}

public class Employee:Person

{

public string Building{get;set;}

public IList<Employee> Resports { get; set; }

public Employee Manager { get; set; }

}

Two new Linq operators are now supported on the client:

- OfType<T>:  used when the type specification needs to happen in the path segment.

- As: used when the type appears in a query option (e.g. $filter, $select, $orderby)

 

Below are some examples of how to query derived properties on the client:

PeopleData ctx = newPeopleData(serviceUri);

// returns only Employee instances

foreach (Employee e in  ctx.People.OfType<Employee>() )

{

. . .

}

// returns a narrow projection that mixes content from Person and Employee

var q = from c in ctx.People

select new EmployeeBuilding { Name = c.FirstName, Building = (c as Employee).Building };

foreach (EmployeeBuilding s in q)

{

               . . .

}

// returns only entities that are Employees working in building 18

var q2 = from p in ctx.People

where (p.FirstName==”Bill” && ((p as Employee).Building == "18"))

select p;

foreach (Employee e in q2)

{

. . .

}

// returns entities of type Person, expanding derived Reports navigation property on the employee instances

foreach (Person p in ctx.People.Expand(p => (p as Employee).Reports))

{

. . .

}

Your feedback is appreciated.

Ahmed Moustafa
Program Manager
WCF Data Services