Today let’s see how to implement a WCF Data Service with Reflection Provider. The reflection provider exposes data in classes which returns an
IQueryable<T>
Scenario
I have three entities which are “Employee”, “Department” and “JobRole”. The relationships among these three entities are as follows.
Let me start off by creating a WCF Service application.
|
Creating a WCF Service Application |
I am deleting the service and it’s interface which was created initially when creating the project. I am going to add latest WCF Data Services references through Nuget. I am searching online for “WCF Data Services Server” and installing it.
|
Adding references through Nuget |
Once all the needed references are installed, I am going to create a class which I am going to name as “MyDataContext”.
I am going to create three classes for each of my entity types.
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
public class JobRole
{
public int JobRoleId { get; set; }
public string JobRoleName { get; set; }
}
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Department Departments { get; set; }
public List<JobRole> JobRoles { get; set; }
}
OK, now you can see I have three classes. In the “Employee” class, I have two properties along with basic properties which are “Departments” and “JobRoles”. By having “Departments” property which is of type “Department”, I am mentioning the department a particular employee belong to. By having list of “JobRoles” which is of type “List<JobRole>”, I am mentioning the job roles a particular employee can have.
Now I need to have primary key fielda for each of these entity types. Of course, I have three properties which are “DepartmentId”,”JobRoleId” and “EmployeeId” which I can use as primary key fields. So for that I am going to decorate the class with the attribute
DataServiceKeyAttribute.
So now I am going to create a method in each of these classes, which will return some data I want to expose to outside.
[DataServiceKeyAttribute("DepartmentId")]
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public static List<Department> GetDepartments()
{
List<Department> deptList = new List<Department>();
deptList.Add(new Department() { DepartmentId = 1, DepartmentName = "Information Technology" });
deptList.Add(new Department() { DepartmentId = 2, DepartmentName = "Finance" });
deptList.Add(new Department() { DepartmentId = 2, DepartmentName = "Human Resources" });
return deptList;
}
}
[DataServiceKeyAttribute("JobRoleId")]
public class JobRole
{
public int JobRoleId { get; set; }
public string JobRoleName { get; set; }
public static List<JobRole> GetJobRoles()
{
List<JobRole> jobRoleList = new List<JobRole>();
jobRoleList.Add(new JobRole() { JobRoleId = 1, JobRoleName = "Software Engineer" });
jobRoleList.Add(new JobRole() { JobRoleId = 2, JobRoleName = "Project Manager" });
jobRoleList.Add(new JobRole() { JobRoleId = 3, JobRoleName = "Accountant" });
jobRoleList.Add(new JobRole() { JobRoleId = 4, JobRoleName = "HR Executive" });
return jobRoleList;
}
}
[DataServiceKeyAttribute("EmployeeId")]
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Department Departments { get; set; }
public List<JobRole> JobRoles { get; set; }
public static List<Employee> GetEmployees()
{
List<Employee> empList = new List<Employee>();
empList.Add(new Employee()
{
EmployeeId = 1,
FirstName = "Jaliya",
LastName = "Udagedara",
Departments = Department.GetDepartments().First(dept => dept.DepartmentName == "Information Technology"),
JobRoles = new List<JobRole>()
{
JobRole.GetJobRoles().First(jobRole => jobRole.JobRoleName == "Software Engineer"),
JobRole.GetJobRoles().First(jobRole => jobRole.JobRoleName == "Project Manager")
}
});
empList.Add(new Employee()
{
EmployeeId = 2,
FirstName = "John",
LastName = "Doe",
Departments = Department.GetDepartments().First(dept => dept.DepartmentName == "Finance"),
JobRoles = new List<JobRole>()
{
JobRole.GetJobRoles().First(jobRole => jobRole.JobRoleName == "Accountant")
}
});
empList.Add(new Employee()
{
EmployeeId = 3,
FirstName = "Jane",
LastName = "Doe",
Departments = Department.GetDepartments().First(dept => dept.DepartmentName == "Human Resources"),
JobRoles = new List<JobRole>()
{
JobRole.GetJobRoles().First(jobRole => jobRole.JobRoleName == "HR Executive")
}
});
return empList;
}
}
Once it is done, I have some entities and some methods which return some data. Now I am going to create my model or the context that I am going to expose through a WCF Data Service.
So I am modifying my “MyDataContext” class as follows.
public class MyDataContext
{
public IQueryable<Employee> Employees
{
get
{
return Employee.GetEmployees().AsQueryable();
}
}
public IQueryable<Department> Departments
{
get
{
return Department.GetDepartments().AsQueryable();
}
}
public IQueryable<JobRole> JobRoles
{
get
{
return JobRole.GetJobRoles().AsQueryable();
}
}
}
I have added three Properties which is of IQueryable<T>. You might be wondering why specially IQueryable<T>, don’t worry about it now, we will discuss about it later.
Now I am almost done. Let’s add a WCF Data Service to the project and put “EntitySetRights.AllRead” as the entity access rule for all the entities, so consumers can read all entities.
using System.Data.Services;
using System.Data.Services.Common;
namespace WCFDataServicesWithReflectionProvider
{
public class WcfDataService1 : DataService<MyDataContext>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
}
Now when I hit F5, I can see the WCF Data Service up and running.
|
WCF Data Service |
When you view the metadata of this service by typing,
http://domain/service.svc/$metadata
you can see the following.
|
metadata |
Now I am going to write the theoretical things related to Reflection Provider. The reason for me to didn’t mention these in the beginning and to mention now is, the best way to understand theory is, comparing it with the practical output.
Of course I will be copy and pasting the things from the MSDN, so you might will bored. But when you contrast them with WCF Data Service we just created, you will find them all interesting.
When you create the data service, the provider infers the data model by using reflection. The following list shows how the reflection provider infers the data model.
So that’s it. I am uploading the sample to my SkyDrive, Enjoy WCF Data Services with Reflection Provider.
Happy Coding.
Regards,
Jaliya