3. Implementing a WCF Service to Access the SQL Azure Database
Now that you have an entity
model of User and Note, you can implement NotepadService, which will
add, update, delete, and search notes. In this section, you will learn
to implement a WCF service and also learn to use Entity Framework to
interact with the SQL Azure database.
3.1. Coding the WCF Contract
In order to create a WCF
service, you must first define a WCF service contract. The following
steps will guide you through how to do this. If everything was
successfully done, you should see a Solution Explorer in Visual Studio
that resembles Figure 9.
Open IService.cs and
replace the content with the following code. The WCF contract will
contain a way to add, delete, update, and search the note in NotepadDB.
Notice here the namespace of System.ServiceModel, which allows you to add attributes ServiceContract and OperationContract, which must be defined in order to create a WCF service.
using System.ServiceModel;
using System.Collections.Generic;
using System;
namespace NotepadServiceRole
{
[ServiceContract]
public interface IService1
{
[OperationContract]
Guid AddUser(Guid userId, string userName);
[OperationContract]
NoteDto AddNote(Guid userId, string notedescription, string noteText);
[OperationContract]
void UpdateNote(int noteId, string noteText);
[OperationContract]
void DeleteNote(Guid userId, int noteId);
[OperationContract]
List<NoteDto> GetNotes(Guid userId);
[OperationContract]
NoteDto GetNote(Guid userId, int noteId);
}
}
In the next section, you will be creating a data contract that will be sent to the client through the service.
3.2. Coding the DataContract
Before you implement the
service contract, you will need to define two data transfer objects to
map to the entity object. Although we can expose the entity generated by
the Entity Framework directly to the WCF service, it is not a
recommended practice because the Entity Framework exposes information
not necessary for the client. For example, information like foreign key,
primary key, and any Entity Framework–related information that is in
the Note and User objects has no
meaning to the client. Also when the Entity Framework object is
serialized, it will include all this unnecessary information, causing
the serialized objects coming through the Internet to get huge, and
since we are working with the Windows Phone over wireless or Wi-Fi
transmission, you will want information sent over the wireless to be
small.
To NotepadServiceRole add the UserDto.cs class with the following code. Notice the namespace that we will be using, System.Runtime.Serialization, which allows you to add DataContract and DataMember attributes that allow the WCF service to serialize this object to be sent over the service to the client.
using System.Runtime.Serialization;
namespace NotepadServiceRole
{
[DataContract]
public class UserDto
{
[DataMember]
public int UserId { get; set; }
[DataMember]
public string Name { get; set; }
}
}
To NotepadServiceRole add the NoteDto.cs class with the following code.
using System.Runtime.Serialization;
namespace NotepadServiceRole
{
[DataContract]
public class NoteDto
{
[DataMember]
public int NoteId { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public string NoteText { get; set; }
}
}
3.3. Coding the Service
In the following steps,
you will implement the NotepadService WCF contract defined in the
foregoing section. You will be using the Entity Framework to access the
SQL Azure database.
Open Service1.svc.cs in the NotepadServiceRole project, and add the code blocks spelled out in the following sections.
3.3.1. Coding AddUser Method
AddUser will add a new user to the database. Notice that you are instantiating NotepadDBEntities, which is the Entity Framework–generated context that connects to the SQL Azure NotepadDB.
public Guid AddUser(Guid userId, string userName)
{
using (var context = new NotepadDBEntities())
{
context.AddToUsers(new User()
{
UserId = userId,
Name = userName,
});
context.SaveChanges();
return userId;
}
}
3.3.2. Coding AddNote Method
Notice here in AddNote method after instantiating NotepadDBEntities, you are creating the Note entity that you generated in the foregoing steps using the Entity Framework Wizard. Once the note is saved, you are mapping to NoteDto to be sent to the client.
public NoteDto AddNote(Guid userId, string notedescription, string noteText)
{
using (var context = new NotepadDBEntities())
{
Note note = new Note()
{
Description = notedescription,
UserId = userId,
NoteText = noteText,
};
context.AddToNotes(note);
context.SaveChanges();
return new NoteDto()
{
NoteId = note.NoteId,
Description = note.Description,
NoteText = note.NoteText,
};
}
}
3.3.3. Coding UpdateNote Method
In order to update the note,
first you need to instantiate the entity context that connects to
NotepadDB, and then you must query for the note that you are going to
update. Once the note is retrieved, you will then update the properties
and save changes.
public void UpdateNote(int noteId, string noteText)
{
using (var context = new NotepadDBEntities())
{
var note = context
.Notes
.Where(n => n.NoteId.Equals(noteId)
).Single();
note.NoteText = noteText;
context.SaveChanges();
}
}
3.3.4. Coding DeleteNote Method
When deleting the note, the note must be retrieved first and then the retrieved note will be added to the DeleteObject of the Notes collection. Then save the changes where the delete will be performed by the Entity Framework.
public void DeleteNote(Guid userId, int noteId)
{
using (var context = new NotepadDBEntities())
{
var note = context
.Notes
.Where(n => n.NoteId.Equals(noteId)).Single();
context.Notes.DeleteObject(note);
context.SaveChanges();
}
}
3.3.5. Coding GetNotes Method
GetNotes will bring all the notes associated with the specific userId.
You will be using a technique called Linq to Entity that closely
resembles the SQL statement. And inside the Linq to Entity, you will be
performing translation of the Note entity to NoteDto. This is a very useful technique for mapping an entity object to a data transfer object.
public List<NoteDto> GetNotes(Guid userId)
{
using (var context = new NotepadDBEntities())
{
var notes = (
from eachNote in context.Notes
where eachNote.UserId == userId
orderby eachNote.Description ascending
select new NoteDto
{
NoteId = eachNote.NoteId,
Description = eachNote.Description,
NoteText = eachNote.NoteText,
}
).ToList();
return notes;
}
}
3.3.6. Coding GetNote Method
GetNote will query a single user note from the database.
public NoteDto GetNote(Guid userId, int noteId)
{
using (var context = new NotepadDBEntities())
{
var notes = (
from eachNote in context.Notes
where eachNote.NoteId == noteId
&& eachNote.UserId == userId
select new NoteDto
{
NoteId = eachNote.NoteId,
Description = eachNote.Description,
NoteText = eachNote.NoteText,
}
).SingleOrDefault();
return notes;
}
}
3.4. Testing Azure WCF NotepadService on Your Machine
You will be testing
NotepadService on your machine so that when you connect to
NotepadService from the Windows Phone Notepad application, you will be
able to debug and step through NotepadService when the service call is
made from the Notepad application.
Press F5 and you will
notice that the Development Fabric window appears with Internet
Explorer. Development Fabric simulates the Azure service environment in
your machine. Notice that when you expand NotepadService you see
NotepadServiceRole, which is the WCF service that you coded in the
foregoing steps. When NotepadService is deployed, you will see one
instance of the service deployed, as shown in Figure 10. Do not stop the service, as you will be referencing the service from the Notepad application.
In the previous steps, you
created the NotepadDB database in SQL Azure and NotepadService hosted
locally using Development AppFabric to simulate Windows Azure. In the
following section, you will be consuming NotepadService from the Notepad
application, and ultimately when the service works properly, you will
be deploying NotepadService to Windows Azure.