Utilizando entidades diferentes com as tabelas do Windows Azure

Olá pessoal,

No post de hoje vou comentar como utilizar entidades diferentes com as tabelas do Windows Azure. Vale lembrar que as tabelas suportam o armazenamento de informações sem forçar a definição de um schema, o que significa que é possível armazenar mais de um tipo de entidade em uma mesma tabela. Vou mostrar rapidamente como incluir entidades diferentes e também como ler essas entidades.

O primeiro passo, é exatamente a definição das entidades, no meu exemplo criei as classes PessoaFisica e PessoaJuridica, ambas herdando da classe Pessoa, esta última herdando de TableEntity para facilitar o trabalho com a estrutura de tabelas. Um ponto interessante de se notar, é a propriedade Tipo que será utilizada mais para frente, na identificação do tipo da entidade no momento da sua leitura.

class Pessoa : TableEntity
{
public string Nome { get; set; }
public string Endereco { get; set; }
public string Tipo { get; set; }
}

class PessoaFisica : Pessoa
{
public string CPF { get; set; }
}

class PessoaJuridica : Pessoa
{
public string CNPJ { get; set; }
}

 

Em seguida, o próximo passo é a inclusão de entidades na tabela. No exemplo abaixo estou utilizando um TableBatchOperation para incluir um objeto do tipo PessoaFisica e outro do tipo PessoaJuridica.

CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount;
CloudTableClient tableClient = account.CreateCloudTableClient();
CloudTable pessoa = tableClient.GetTableReference("Pessoa");
pessoa.CreateIfNotExists();

TableBatchOperation batch = new TableBatchOperation();
PessoaFisica pf = new PessoaFisica()
{
PartitionKey = "1",
RowKey = Guid.NewGuid().ToString(),
Nome = "José da Silva",
Endereco = "Rua A",
CPF = "123.456.789-00",
Tipo = "PF"
};

PessoaJuridica pj = new PessoaJuridica()
{
PartitionKey = "1",
RowKey = Guid.NewGuid().ToString(),
Nome = "Empresa do José",
Endereco = "Rua B",
CNPJ = "111222333444555666777888999000",
Tipo = "PJ"
};

batch.Insert(pf);
batch.Insert(pj);

pessoa.ExecuteBatch(batch);

 

Em seguida, para a leitura é possível utilizar um delegate do tipo EntityResolver permitindo uma lógica customizada na resolução do tipo do objeto, neste ponto que utilizo a propriedade Tipo da classe Pessoa. Além disso, também utilizo o método ReadEntity, original da classe TableEntity, para popular as propriedades dos objetos.

EntityResolver<Pessoa> pessoaResolver = (pk, rk, ts, props, etag) =>
{
Pessoa pessoaResolvida = null;
string tipo = props["Tipo"].StringValue;

        if (tipo == "PF") { pessoaResolvida = new PessoaFisica(); }
else if (tipo == "PJ") { pessoaResolvida = new PessoaJuridica(); }

        pessoaResolvida.PartitionKey = pk;
pessoaResolvida.RowKey = rk;
pessoaResolvida.Timestamp = ts;
pessoaResolvida.ETag = etag;
pessoaResolvida.ReadEntity(props, null);

        return pessoaResolvida;
};

TableQuery<Pessoa> query = new TableQuery<Pessoa>();
var pessoas = pessoa.ExecuteQuery(query, pessoaResolver);

foreach (var item in pessoas)
{
Console.WriteLine("Nome: {0} - Tipo: {1}",
item.Nome,
item.Tipo);
}

Se vc quiser fazer o download deste código, ele pode ser encontrado aqui

RG