有没有人知道查询azure表存储空值的正确方法。从我所读到的,它是可能的(虽然有一个错误阻止它在开发存储上)。但是,当我在实时云存储上执行此操作时,我一直收到以下错误:
其中一个请求输入无效。
这是我放在一起的LINQ查询的一个愚蠢版本。
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;
如果我在不检查null的情况下运行查询,它可以正常工作。我知道一个可能的解决方案是对该查询带回的集合运行第二个查询。如果我需要,我不介意这样做,但想知道我是否可以先采用这种方法。
有人看到任何明显我做错的事吗?
答案 0 :(得分:41)
问题是因为azure表存储没有架构,所以null列实际上不存在。这就是您的查询无效的原因。表存储中没有空列。如果你真的需要,你可以做一些像存储空字符串的事情。实际上,这里的根本问题是Azure表存储确实不是由除分区键和行键之外的任何列来查询的。每次对其中一个非标准列进行查询时,您都在进行表扫描。如果您开始获得大量数据,那么查询超时率将会非常高。我建议为这些类型的查询设置手动索引。例如,您可以将相同的数据存储在同一个表中,但Row键的值不同。最终,如果您的应用程序没有疯狂的高使用率,我会使用SQL Azure,因为它对您正在进行的查询类型将更加灵活。
更新:Azure有一个关于表存储设计的精彩指南,我建议您阅读。 http://azure.microsoft.com/en-us/documentation/articles/storage-table-design-guide/
答案 1 :(得分:1)
我只是遇到了这个问题,发现了一个不错的忍者小技巧来实际测试null。尽管我直接使用Azure存储界面,但我90%确信如果您这样做也同样适用于LINQ。
这是我要检查价格(Int32?)是否为空的事情:
not (Price lt 0 or Price gt 0)
我想在您的情况下,可以通过测试fooBar.Termination_Date是否小于或大于DateTime.UtcNow在LINQ中执行相同的操作。像这样:
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;
答案 2 :(得分:1)
对于字符串,我们可以比较空字符串。
IsNotBlank(value)
可以是:
(Value gt '')
答案 3 :(得分:0)
对于名为 MyColumn 的字符串列,我可以输入:not(MyColumn gt '')
上述 Mike S 的回答让我走上了正确的道路。