Pergunta

Alguém sabe a maneira correta de consultar o armazenamento da tabela do Azure por um valor nulo. Pelo que li, é possível (embora exista um bug que o impeça no armazenamento de desenvolvimento). No entanto, continuo recebendo o seguinte erro quando o faço no Live Cloud Storage:

Uma das entradas de solicitação não é válida.

Esta é uma versão emburrecida da consulta LINQ que eu reuni.

var query = from fooBar in fooBarSVC.CreateQuery<FooBar>("FooBars")
        where fooBar.PartitionKey == kPartitionID
            && fooBar.Code == kfooBarCode
            && fooBar.Effective_Date <= kFooBarDate.ToUniversalTime()
            && (fooBar.Termination_Date > kFooBarDate.ToUniversalTime() || fooBar.Termination_Date == null)
        select fooBar;

Se eu executar a consulta sem verificar o NULL, funciona bem. Sei que uma possível solução seria executar uma segunda consulta na coleção que essa consulta traz de volta. Não me importo de fazer isso, se precisar, mas gostaria de saber se consigo obter essa abordagem para funcionar primeiro.

Alguém vê algo óbvio que estou fazendo de errado?

Foi útil?

Solução

O problema é que, como o armazenamento da tabela do Azure não possui um esquema, a coluna nula realmente não existe. É por isso que sua consulta não é válida. Não existe uma coluna nula no armazenamento de tabela. Você pode fazer algo como armazenar uma corda vazia, se for necessário. Realmente, embora a questão fundamental aqui seja que o armazenamento da tabela do Azure realmente não tenha sido criado para ser consultado por nenhuma coluna que não seja a chave de partição e a tecla de linha. Toda vez que você faz uma consulta em uma dessas colunas fora do padrão, você está fazendo uma varredura de mesa. Se você começar a obter muitos dados, terá uma taxa muito alta de intervalos de consulta. Eu sugeriria configurar um índice manual para esses tipos de consultas. Por exemplo, você pode armazenar os mesmos dados na mesma tabela, mas com valores diferentes para a chave da linha. Por fim, se o seu aplicativo está recebendo um alto uso louco, eu usaria apenas o SQL Azure, pois será muito mais flexível para os tipos de consultas que você está fazendo.

ATUALIZAÇÃO: O Azure tem um ótimo guia sobre o design de armazenamento de mesa que eu recomendaria a leitura. http://azure.microsoft.com/en-us/documentation/articles/storage-tabable-design-guide/

Outras dicas

Acabei de ter esse problema e encontrei um belo ninja-trick para realmente testar os nulos. Embora eu esteja usando a interface de armazenamento do Azure diretamente, tenho 90% de certeza de que ele também funcionará para o LINQ se você fizer o mesmo.

Aqui está o que eu fiz para verificar se o preço (int32?) É NULL:

not (Price lt 0 or Price gt 0)

Suponho que, no seu caso, você pode fazer o mesmo no LINQ testando se o foobar.Verminen_Date for menos ou maior que o DateTime.utcNow, por exemplo. Algo assim:

where fooBar.PartitionKey == kPartitionID
  && fooBar.Code == kfooBarCode
  && fooBar.Effective_Date <= kFooBarDate.ToUniversalTime()
  && (fooBar.Termination_Date > kFooBarDate.ToUniversalTime()
  || (not (fooBar.Termination_Date < DateTime.UtcNow 
            or fooBar.Termination_Date > DateTime.UtcNow))
select fooBar;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top