Table Storage do Azure. Criamos uma classe "Usuario", pra ser armazenada "lá" (na(s) nuvem(ns)). Baseando o código num dos exemplos que encontramos por aí, tudo rodou ok.
"Beleza", digo eu. "Vamos codificar na vera agora". Bem, estávamos usando o identificador da empresa como Partition Key, e o e-mail do usuário como Row Key. Só que meu código estava meio torto. Por exemplo, pra acessar o e-mail do usuário a gente escrevia
string email = Usuario.RowKey; // Usuario.RowKey???
Pra acessar a empresa:
int codigoEmpresa = Usuario.PartitionKey; // Hã?
Obviamente, quero usar Usuario.EMail e Usuario.CodigoEmpresa. Aí começou meu quebra-pau com o Azure.
Quando a gente cria uma classe que representa as entidades (= linhas) de uma tabela (= tabela) no Table Storage do Azure, esta classe tem que ser marcada com o atributo DataServiceKeys. No exemplo de código que pegamos, a classe estava marcada com
[DataServiceKeys("PartitionKey", "RowKey"]
public class Usuario
{
int PartitionKey { get; set; }
string RowKey { get; set; }
//... Resto do código
}
"Simples", penso eu. "É só especificar o nome das propriedades que serão as Partition e Row Keys naquele atributo". Rá. Ledo engano. (Não sei o que é "ledo", mas sempre que você está totalmente enganado, o engano é um "ledo engano"). Mudei o nome das propriedades PartitionKey e RowKey para CodigoEmpresa e EMail. Renomeei as propriedades no código. Recompilei. Tudo ok.
[DataServiceKeys("CodigoEmpresa ", "EMail "]
public class Usuario{
int CodigoEmpresa { get; set; }
string EMail { get; set; }
//... Resto do código
}
Aí fui rodar o DevTableGen para gerar as tabelas no Development Storage. A tabela de usuários não foi gerada.
Peculiaridade nº 1: Se o atributo DataServiceKeys não recebe literalmente as strings "PartitionKey" e "RowKey" como parâmetro, o DevTableGen não gera a tabela.
[DataServiceKeys("PartitionKey", "RowKey"]
public class Usuario{
int PartitionKey { get; set; } // aqui vai ficar o código da empresa
string RowKey { get; set; } // aqui vai ficar o e-mail do usuário
// Por aqui eu leio o código da empresa
int CodigoEmpresa {
get { return PartitionKey; }
}
// Por aqui eu leio o e-mail do usuário
string EMail {
get { return RowKey; }
}
//... Resto do código
}
Coloquei propriedades read-only somente para poder dar acesso às informações que estão em PartitionKey e RowKey, mas com nomes que fazem mais sentido para a minha classe ("mais de acordo com o domínio do problema", como diriam os cientificamente corretos). Só que o DevTableGen não gerou a tabela Usuario, pois (peculiaridade nº 2) ele se recusa a gerar a tabela se há propriedades read-only na classe.
"OMLE", pensei. "Oh My Left Egg". Já cansado desta discussão e sem pensar direito, coloquei então o set das propriedades CodigoEmpresa e EMail:
[DataServiceKeys("PartitionKey", "RowKey"]
public class Usuario
{
int PartitionKey { get; set; } // aqui vai ficar o código da empresa
string RowKey { get; set; } // aqui vai ficar o e-mail do usuário
// Por aqui eu leio o código da empresa
int CodigoEmpresa {
get { return PartitionKey; }
set { PartitionKey = value; }
}
// Por aqui eu leio o e-mail do usuário
string EMail {
get { return RowKey; }
set { RowKey = value; }
}
//... Resto do código
}
A consequência (óbvia, por sinal) é que o DevTableGen gerou a tabela com ambos os pares de propriedades: agora eu tinha uma tabela de usuários que guardava o código da empresa em PartitionKey e CodigoEmpresa, e o e-mail em RowKey e EMail. Não interessa para ele se a propriedade é só uma "acessora" (accessor) a valores armazenados em outro lugar; a propriedade existe, então ele gera uma coluna pra ela.
Ainda fiz mais algumas tentativas, mas no final das contas acabei com a classe Usuario guardando o código da empresa em PartitionKey e o e-mail do usuário em RowKey, e acrescentando outra sugestão no Connect, pra ver se a Microsoft dá um jeito nisto.A resposta foi "Obrigado por reportar esta situação. Vamos mandar para o time e blablabla vão ver se implementam para a próxima versão". Hum. Quero só ver...