Add a new class called AddressTableContext to inherit from the base class TableContext, as shown in Listing 2-3.. The purpose of creating this class is to encapsulate the table storage i
Trang 128
Figure 2-2 The AddressTableContext class diagram
3 Add a new class called AddressTableContext to inherit from the base class TableContext, as shown in Listing 2-3 The purpose of creating this class is to encapsulate the table storage interface function to a specific data table In this exercise we only access the Address table, so we only need to create one derived class from TableContext If there are multiple tables we need to access then we need to create more classes derived from TableContext in the future Each derived class is dedicated to a specific data table So why can't we come
up with a generic table-access class, which exposes the data table access functions and returns generic types The answer is the table name is a static string and needs to match the name of the physical data storage table Another reason is that this allows the client code to accept the return data table type as
a concerte type without transforming the generic type This will significantly reduce unnecessary complexity To reach that end there are three tasks that need to be done
1 Create a constructor to this class to accept a parameter of instance of StorageAccountInfo
2 Read the table name from the configuration settings in the body of the constructor
3 Add a query interface to query the Address table
Trang 229
Listing 2-3 Implementation of Class AddressTableContext, a Derived Class of TableContext
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
namespace CloudTableStorageService WebRole.CloudTableStorageDataContext
{
using Microsoft.Samples.ServiceHosting.StorageClient;
using CloudTableStorageService WebRole.CloudTableStrorageDataEntity;
internal class AddressTableContext : TableContext
{
internal AddressTableContext(StorageAccountInfo accountInfo)
: base(accountInfo)
{
TableName = ConfigurationManager.AppSettings["AddressTable"];
}
public IQueryable<Address> AddressTable
{
get { return CreateQuery<Address>(TableName); }
}
}
}
4 In the CloudTableStorageService WebRole project create a C# class called
DataTableService and mark it as an abstract class since we are going to use it
as a base class This class implements the facade design pattern to encapsulate
the StorageAccountInfo and TableContext classes The definition of this base
class is shown in Listing 2-4
Listing 2-4 Definition of Base Class DataTableService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace CloudTableStorageService WebRole.CloudTableStorageDataService
{
using Microsoft.Samples.ServiceHosting.StorageClient;
using CloudTableStorageService WebRole.CloudTableStorageDataContext;
abstract public class DataTableService
{
protected StorageAccountInfo account = null;
protected TableContext dataTableContext = null;
Trang 330
public DataTableService()
{
// Get the settings from the Service Configuration file
account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration(); }
public TableContext TableContext() { return dataTableContext; }
}
}
5 Add a new C# class AddressTableService in the same folder (The class diagram
is shown in Figure 2-3 The implementation for the class is shown in Listing 2-5.) This class is derived from the base class DataTableService and provides a set of public access functions to perform basic data I/O between the table storage context and the custom-defined data entity container classes This class must have at least the next four public methods:
• Select(): The Select() method can include functionality to retrieve an enumerable collection of data items and to retrieve a single item In this example we are going to implement Select() to retrieve the enumerable item collection from the table AddressTable
• Insert(): To insert an entity into a cloud storage table; in this example, to the table AddressTable
• Update(): To refresh changes of a data entity to a cloud storage table; in this example, to the table AddressTable
• Delete(): To remove a data entity from a cloud storage table; in this example, from the table AddressTable
Figure 2-3 Class AddressTableService provides data IO services
Trang 431
Listing 2-5 Implementation of the Class AddressTableService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Services.Client;
using System.Configuration;
namespace CloudTableStorageService WebRole.CloudTableStorageDataService
{
using Microsoft.Samples.ServiceHosting.StorageClient;
using CloudTableStorageService WebRole.CloudTableStrorageDataEntity;
using CloudTableStorageService WebRole.CloudTableStorageDataContext;
public class AddressTableService : DataTableService
{
/// </summary>
public AddressTableService()
{
dataTableContext = new AddressTableContext(base account);
dataTableContext.RetryPolicy =
RetryPolicies.RetryN(Convert.ToInt32(
ConfigurationManager.AppSettings["Retry"]),
TimeSpan.FromSeconds(1));
}
public IEnumerable<Address> Select()
{
if (null == dataTableContext ||
null == ( dataTableContext as AddressTableContext))
{
return null;
}
var results =
from a in ( dataTableContext as AddressTableContext).AddressTable select a;
if (0 == (results as
DataServiceQuery<Address>).ToArray<Address>().Count<Address>())
{
return null;
}
TableStorageDataServiceQuery<Address> query =
new TableStorageDataServiceQuery<Address>(
results as DataServiceQuery<Address>);
IEnumerable<Address> queryResults = query.ExecuteAllWithRetries();
return queryResults;
}
Trang 532
public bool Insert(Address entity)
{
bool success = false;
try
{
dataTableContext.AddObject( dataTableContext.TableName, entity); dataTableContext.SaveChanges();
success = true;
}
catch { }
return success;
}
public bool Update(Address entity)
{
bool success = false;
try
{
if (Delete(entity))
{
success = Insert(entity);
}
}
catch { }
return success;
}
public bool Delete(Address entity)
{
bool success = false;
try
{
dataTableContext.AttachTo( dataTableContext.TableName, entity, "*"); dataTableContext.DeleteObject(entity);
dataTableContext.SaveChanges();
success = true;
}
catch { }
return success;
}
}
}
6 Open AddressTable.aspx from the project in Visual Studio and insert two table objects into the body of the form as Figure 2-4 shows