Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

WCF and LINQ

2.86/5 (8 votes)
22 Jul 2008CPOL3 min read 1  
A WCF web service that queries a database table using LINQ, returning the resulting collection

Introduction

In this article, a web service with HTTP binding is created, exposing a method that queries a database table using LINQ. The method is defined in the service contract of the WCF service. Each resulting record from the LINQ query is populated in an object that is defined in a data contract of the WCF service. The collection of objects is then returned by the service method as a generic IEnumerable collection.

Defining the WCF Service

We first create the WCF service in Visual Studio 2008 and version 3.5 of .NET, using the wsHttp binding. The service is defined in the web.config file, as follows:

XML
<services>
   <service name="SomeService" behaviorConfiguration="ServiceBehavior">
       <endpoint address=""  binding="wsHttpBinding" contract="ISomeService">
          ...

Note how the address attribute of the endpoint is left blank for now, letting IIS use a default address. This can be changed to a fixed address at deployment time.

We then define the service contract in the ISomeService.cs file. The service contract is where all the service methods are defined:

C#
[ServiceContract]
public interface ISomeService
{
   [OperationContract]
   string GetData(int value);

   [OperationContract]
   IEnumerable<EmpRecord> GetEmpData(string empLastName);
}

We have two methods defined, the first one is just a simple method that returns a string based on an int passed in as an argument. The second method, which is the one that is of real interest to us, accepts a last name of an employee and returns a collection of EmpRecord objects. The EmpRecord class is defined in the data contract of the service, also in the ISomeService.cs file, as follows:

C#
[DataContract]
public class EmpRecord
{
   int id = 0;
   string fName = "";
   string lName = "";
   string state = "";
   
  [DataMember]
  public int Id
  {
     get { return id; }
     set { id = value; }
  }
 
  [DataMember]
  public string First
  {
     get { return fName; }
     set { fName = value; }
  }
  
  [DataMember]
  public string Last
  {
     get { return lName; }
     set { lName = value; }
  }
  
  [DataMember]
  public string State
  {
     get { return state; }
     set { state = value; }
  }
}

The EmpRecord class is defined as a data contract in the WCF service, with four private fields and four corresponding public properties to get and set the field values.

In the SomeService.cs file of the WCF project, we implement the service interface and methods that we defined above, as follows:

C#
public class SomeService : ISomeService
{
   public string GetData(int value)
   {
       return string.Format("You entered: {0}", value);
   } 
   
   public IEnumerable<EmpRecord> GetEmpData(string empLastName)
   {
       LinqDataClassesDataContext ctxt = new LinqDataClassesDataContext();
       
       return from r in ctxt.Employees
              where r.lName.Contains(empLastName)
              select new EmpRecord 
		{ Id = r.ID, First = r.fName, Last = r.lName, State = r.state};
    }
}

A LINQ expression is used in the body of the GetEmpData method to query the Employee table, returning all rows that have their lName fields containing the last name string passed in as an argument. The Employee table is made up of the following fields: ID, fName, lName, City, and State. All matching rows are returned by the method as an IEnumerable collection. The LinqDataClassesDataContext is defined in the DBML file of our WCF service project, which is basically a LINQ to SQL data context object. We created this data context object by visually dropping our database tables into the LINQ to SQL DBML file that we added to our WCF project.

Consuming the WCF Service

To consume the WCF service, we create an ASP.NET web application project, and add a service reference to it in the Solution Explorer. We then create an instance of the service and call the appropriate methods, such as:

C#
protected void Page_Load(object sender, EventArgs e)
{
   SomeSvc.SomeServiceClient someSrvc = new SomeSvc.SomeServiceClient();
   var coll = someSrvc.GetEmpData("Evans");

   GridView2.DataSource = coll;
   GridView2.DataBind();
}

SomeSvc is the name of the service reference that I added to my ASP.NET web app project, which gives us access to the client proxy class. I then call the GetEmpData method, passing an employee last name, and bind the returned collection of matching EmpRecord objects to a gridview.

Alternatively, we can just iterate through the collection of EmpRecord objects, as shown below:

C#
bool bFound = false;
foreach (SamSvc.EmpRecord empl in coll)
{
    if (empl.State.IndexOf("FL") >= 0)
    {
        bFound = true;
        break;
    }
}

Points of Interest

  • The simplicity of defining our own objects as data contracts in a WCF service, and making use of easy to use LINQ expressions to encapsulate returned database records in those objects.
  • Similarly, service contracts make it fairly straightforward to define our own methods in the WCF service, accepting and returning our own defined objects.

History

  • 22nd July, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)