Azure: Una aplicación simple usando Tables

Published on Author lopezLeave a comment

Continuando con mis ejemplos de Azure, esta vez escribí una simple aplicación web CRUD, usando Tables, con Tables, usando Azure Storage Client.

Es una aplicación de ASP.NET clásico, con esta vista para CustomerList.aspx:

Pueden bajarse la solución desde mi AjCodeKatas Google project. El código está en:

http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/Azure/AzureCustomers

Si quieren pueden bajarse directamente la versión “congelada” desde: AzureCustomers.zip.

La simple entidad Customer:

public class Customer : TableServiceEntity
{
    public Customer()
        : this(Guid.NewGuid().ToString())
    {
    }
    public Customer(string id)
        : base(id, string.Empty)
    {
    }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Notes { get; set; }
}

Estoy usando la PartitionKey como clave primaria, llenándola con un Guid. La RowKey es el string vacío. En una aplicación menos simple, podría grabar las facturas de un cliente usando la misma Partition Key, identificando cada factura con un RowKey distinto.

Un DataContext está a cargo de exponer un IQueryable de Customers:

public class DataContext : TableServiceContext
{
    public const string CustomerTableName = "Customers";
    public DataContext(string baseAddress, StorageCredentials credentials)
        : base(baseAddress, credentials)
    {
        this.IgnoreResourceNotFoundException = true;
    }
    public DataContext(CloudStorageAccount storageAccount)
        : base(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials)
    {
        this.IgnoreResourceNotFoundException = true;
    }       
    public IQueryable<Customer> Customers
    {
        get
        {
            return this.CreateQuery<Customer>(CustomerTableName);
        }
    }
}

Noten el IgnoreNotFoundException: si está en verdadero, puedo recuperar un cliente inexistente sin levantar una excepción, y retornar un valor null.

Hay un servicio para acceder y manejar los Customers:

public class CustomerServices
{
    private DataContext context;
    public CustomerServices(DataContext context)
    {
        this.context = context;
    }
    public Customer GetCustomerById(string id)
    {
        return this.context.Customers.Where(c => c.PartitionKey == id).SingleOrDefault();
    }
    public IEnumerable<Customer> GetCustomerList()
    {
        return this.context.Customers.ToList().OrderBy(c => c.Name);
    }
    public void AddCustomer(Customer customer)
    {
        this.context.AddObject(DataContext.CustomerTableName, customer);
        this.context.SaveChanges();
    }
    public void UpdateCustomer(Customer customer)
    {
        this.context.AttachTo(DataContext.CustomerTableName, customer, "*");
        this.context.UpdateObject(customer);
        this.context.SaveChanges();
    }
    public void DeleteCustomerById(string id)
    {
        Customer c = this.GetCustomerById(id);
        this.context.DeleteObject(c);
        this.context.SaveChanges();
    }
}

Noten el uso de Attach con ETag (tercer parámetro) de “*” (any). De esta forma, podemos actualizar el cliente adosando el “creado en memoria” al contexto de datos, sin recuperalo desde la base de datos. Esta forma de hacerlo es viable si tengo todos los datos del cliente, y no me importa sobreescribir cambios posibles que se hubieran hecho en el storage. En muchas aplicaciones uno cambia solamente parte del estado, ante una operación (por ejemplo, cambio de domiciolio). Entonces se recupera el objeto, se cambia parte del estado y se lo graba.

Usando el servico para recuperar los clientes:

CloudStorageAccount storage = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
CustomerServices services = new CustomerServices(new DataContext(storage));
this.grdCustomerList.DataSource = services.GetCustomerList();
this.grdCustomerList.DataBind();

Nota: ésta es una aplicación de ejemplo, simple y directa. Una aplicación real debería separar el modelo de vista del modelo de negocio, y posiblemente, usar ASP.NET MVC en la presentación. Escribiré este ejemplo usando MVC. En otra serie (fuera de ésta relacionado con Azura), quiero escribir una aplicación ASP.NET MVC usando TDD.

Próximos pasos en Azure: una aplicación distribuida que calcule un fractar, un web crawler distribuido, un algoritmo genético usando Worker Roles.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Leave a Reply

Your email address will not be published. Required fields are marked *