Reading data from an Entity Framework data model through a WCF Data Service
This is going to be the fourth post of a series of posts regarding ASP.Net and the Entity Framework and how we can use Entity Framework to access our datastore. You can find the first one here, the second one here and the third one here.
I have a post regarding ASP.Net and EntityDataSource. You can read it here.I have 3 more posts on Profiling Entity Framework applications. You can have a look at them here, here and here.
Microsoft with .Net 3.0 Framework, introduced WCF. WCF is Microsoft's choice to design/build Service Oriented Architecture applications. In this post I will not be hitting the database directly in a connected way. I will use a WCF data service to work with the data in a disconnected, n-tier way.
I assume that you have access to a version of SQL Server.If you do not, you can download and install the free SQL Server Express edition from here. In this post (step 9)you will find a T-SQL script that will create the database objects of the CompanyEmployees database.Before that you execute the T-SQL script you must create in the Query window the CompanyEmployees database yourself. You can download the companiesemployeesinsertt.zip to insert data into the tables. 1) Launch Visual Studio 2010 (express edition will work fine). Create an ASP.Net web application from the available templates and choose a suitable name for it. Choose C# as the development language. 2) Add a new ADO.Net Entity Data model to the project. Choose a suitable name for it, e.g CompanyEmployees.edmx. 3) Then the Wizard pops up. Choose "Generate from Database".Choose the database which you will base the model on , CompanyEmployees.Follow exactly the steps 5-9 that you can see in this post to finish the steps of the wizard.Now you have your entity data model. 4) Now we will add the WCF data service. Add another item to your project. From the available templates select WCF Data Service. Name it CompEmp.svc. 5) When you do that, you will see some new references added to the project. The most important is System.ServiceModel.Inside this namespace are all of the classes and methods necessary to build all our services. Inside my CompEmp.svc.cs file, I have this code that was generated for me
namespace N_tier2
{
public class CompEmp : DataService< /* TODO: put your data source class name here */ >
{
// 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("MyEntityset", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
}
We must change this line of code
public class CompEmp : DataService< /* TODO: put your data source class name here */ >
with this one
public class CompEmp : DataService<CompanyEmployeesEntities>
What we did here, is to "connect" the WCF service to our data model. 6) Now you can build and run your project. In the browser window you will see something like this So now we see that our service is up and running. We have our WCF Service(REST service) accessing our database through the Entity data model.Now in order to see the actual data we must tell the WCF service what data we want to access. I will change this line of code in the CompEmp.svc.cs file
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<service xmlns="http://www.w3.org/2007/app" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xml:base="http://localhost:4441/CompEmp.svc/"> -<workspace> <atom:title>Default</atom:title> </workspace> </service>
// config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
with this one
config.SetEntitySetAccessRule("*", EntitySetRights.All);
With the line above we basically say that the WCF Service can access all the entities in the model and can do all operations on them (read,create,delete,update) Run your application again. Under the url, http://localhost:4441/CompEmp.svc/Employees (in your case it will be slightly different) you will see the Employees data. We can get the details for a specific employee by typing http://localhost:4441/CompEmp.svc/Employees(3) 7) We will create a new web application that will consume the WCF Service. Add a new project to the solution, a web application. Name it ConsumeWCF. Then we need to add a service reference to the project.This will play the role of the gateway to the project that contains the WCF service. In this web application in the Solutions Explorer go to References and then Add Service Reference. See the picture below in order to complete the steps. Basically you will find the service that exists in the same solution. 8) In the ConsumeWCF web application, in the Default.aspx page add a bulletedlist web server control.
<asp:BulletedList ID="BulletedList1" runat="server">
</asp:BulletedList>
In the Page_Load event handling routine of the Default.aspx page type
try
{
CompanyEmployeesEntities ctx = new CompanyEmployeesEntities(new Uri
("http://localhost:4441/CompEmp.svc"));
foreach (Company comp in ctx.Companies)
{
BulletedList1.Items.Add(string.Format("{0} {1}",comp.CompanyID,
comp.CompanyName));
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
In this simple bit of code I instantiate the class that represents the service. Run your application and see the data printed on the screen. 10) Let's write a more complicated query to get more data from the database through the WCF service that accesses the Entity data model. Add a button on the About.aspx page. Add a bulletedlist web server control on the same page. In the Button1_Click event handling routine of the About.aspx page type
try
{
CompanyEmployeesEntities ctx = new CompanyEmployeesEntities(new Uri
("http://localhost:4441/CompEmp.svc"));
var query = from emp in ctx.Employees
where emp.EmpFirstName.StartsWith("Le") && emp.Country == "Iran"
orderby emp.Country descending
select emp;
foreach (var item in query)
{
BulletedList1.Items.Add(string.Format("{0} {1}", item.EmpLastName,
item.EmpFirstName));
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
Run your application and see the results printed on the screen. Hope this helps!!!