Descobri ontem que nem tudo que funciona no Azure de verdade funciona durante o desenvolvimento com o Development Fabric e Development Storage, ao menos não durante o CTP atual. No caso, o que eu estava testando é a criação de tabelas dinamicamente, através de código. Não funciona. Além disso, várias outras não funcionam também, segundo o MSDN.
Se você se aventurar a criar uma tabela dinamicamente receberá o belo erro:
“Creating a new table dynamically is not supported in development storage”
Então, para quem quiser por algum código para testar com o Azure Table Storage, só resta o Azure de verdade? Não, há uma ferramenta feita para a criação da tabela do table storage, chamada DevTableGen. Você chama ela com os parâmetros corretos e tudo funciona (notem o “Windows Azure SDK Environment – tem até prompt de comando para Azure):
Só que eu penei até descobrir. Há restrições nas entidades, você é obrigado a criar uma entidade que tenha as propriedades “PartitionKey” e “RowKey”, não pode dar a elas o nome que quiser.
Espero que resolvam isso logo… O código que eu estava usando antes para criar a tabela dinamicamente era bem mais simples do que ter ficar usando ferramenta de linha de comando. Vejam a classe de contexto:
public class AzureContext : TableStorageDataServiceContext { public TableStorage TableStorage { get { var account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration(); var ts = TableStorage.Create(account); return ts; } } public IQueryable<Models.Message> Messages { get { return this.CreateQuery<Models.Message>("Message"); } } }
Depois chamava simplesmente a propriedade TableStorage e criava a tabela. Vejam a ação (com ASP.Net MVC):
[AcceptVerbs(HttpVerbs.Post)] public ActionResult CreateTables(string tableName) { var ctx = new MvcApplication1.AzureContact.AzureContext(); var tableCreated = ctx.TableStorage.TryCreateTable(tableName); if (tableCreated) TempData.Add("tablescreated", "Tables created sucessfully"); else TempData.Add("tablescreated", "Tables already existed"); return RedirectToAction("CreateTables"); }
Simples, certo? Mas não funciona na nuvem, durante o deseenvolvimento você recebe uma bela exceção de presente. Na nuvem eu testei, funciona.
Vocês viram a propriedade “Messages”, que retorna um “IQueryable<Message>”? Pois é, o DevTableGen usa esta informação para criar a tabela, ele reflete o assembly, procura por classes que herdam de DataServiceContext (como “TableStorageDataServiceContext”, da qual meu “AzureContext” herda), e nestas classes procurar por “IQueryable”s que tenham tipos com os atributos corretos (“DataServiceKey”) e as duas propriedades obrigatórias. Se você não fizer tudo direitinho recebe uma bela mensagem de erro do DevTableGen:
DevTableGen : error DG10 : No tables were generated. Either no candidate classes were found or they did not meet the requirements for the table storage.
Vejam a entidade:
[DataServiceKey("PartitionKey", "RowKey")] public class Message { //sender public string PartitionKey { get; set; } //date sent public string RowKey { get; set; } public string Body { get; set; } public string Subject { get; set; } public int Length { get; set; } public Message() { } public Message(string sender, string body) { this.PartitionKey = sender; this.Body = body; this.RowKey = DateTime.UtcNow.ToShortDateString(); this.Length = body.Length; } }
Outra coisa engraçada é que o Development Storage (DS) não é assim tãããããããão avançado quanto eu pensava. O que ele faz é criar uma tabela de verdade no banco de dados, igualzinho o esquema da classe. Dêem uma olhada:
É claro que a implementação em produção, na nuvem, não é assim. Lá você pode usar uma “tabela” virtual para guardar objetos de tipos diferentes, o que seria incompatível com esse tipo de design. Imagino que também não deve ser possível trocar o esquema da entidade e continuar usando o development storage, provavelmente você teria que recriá-lo (com o DevTableGen).
Quando anunciaram que o DS era a nuvem na sua casa eu pensei “uau, os caras fizeram algo poderoso só para eu poder simular o que acontece de verdade”. Não é bem, assim, não é?
Bom, estamos em CTP, certo? Não dá para exigir tanto, mas eles bem que podiam avisar que era “quase” igual, para não criar uma expectativa que depois não é atendida. Vamos aguardar o próximo CTP para ver se isso é resolvido. Na prática, o impacto durante o desenvolvimento é mínimo.
Giovanni Bassi
Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.