我正在使用Windows Azure表存储并且有一个简单的要求:添加一个新行,用PartitionKey/RowKey覆盖任何现有行.但是,即使我传入ReplaceOnUpdate选项,保存更改也会引发异常:
tableServiceContext.AddObject(TableName, entity);
tableServiceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
Run Code Online (Sandbox Code Playgroud)
如果实体已存在,则抛出:
System.Data.Services.Client.DataServiceRequestException: An error occurred while processing this request. ---> System.Data.Services.Client.DataServiceClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>EntityAlreadyExists</code>
<message xml:lang="en-AU">The specified entity already exists.</message>
</error>
Run Code Online (Sandbox Code Playgroud)
我是否真的必须首先手动查询现有行并调用DeleteObject它?这似乎很慢.当然有更好的方法吗?
我有一个Azure存储表,它有3k +记录.
删除表中所有行的最有效方法是什么?
使用此代码块
try
{
StorageCredentials creds = new StorageCredentials(accountName, accountKey);
CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
CloudTableClient client = account.CreateCloudTableClient();
CloudTable table = client.GetTableReference("serviceAlerts");
TableOperation retrieveOperation = TableOperation.Retrieve<ServiceAlertsEntity>("ServiceAlerts", "b9ccd839-dd99-4358-b90f-46781b87f933");
TableResult query = table.Execute(retrieveOperation);
if (query.Result != null)
{
outline = outline + ((ServiceAlertsEntity) query.Result).alertMessage + " * ";
}
else
{
Console.WriteLine("No Alerts");
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Run Code Online (Sandbox Code Playgroud)
我能够使用检索中提到的分区和rowkey检索单个记录.
有没有办法可以获得存储在ServiceAlerts分区中的所有记录?
我已尝试使用通配符(*)作为第二个参数
TableOperation retrieveOperation = TableOperation.Retrieve<ServiceAlertsEntity>(
"ServiceAlerts","b9ccd839-dd99-4358-b90f-46781b87f933");
Run Code Online (Sandbox Code Playgroud)
但它不会返回任何东西.
我有一个大约500万行的天蓝色表,每个分区大约有10万行.RowKey是一个可排序的时间戳.我需要能够获得插入表中的最新记录.
由于不支持Linq Last,Max,OrderBy等,我如何有效地获取最新的表记录?
目前,我正在使用PartitionKey来区分将数据存储到Azure Table Services的设备.我想构建一个允许我浏览该数据的查看器,但能够构建它以便我可以"通过设备"或通过PartitionKey查看数据会很好.查看器应用程序将不知道存在哪些设备,因此如果我能以某种方式返回给定表中的不同PartionKeys列表,那将会很棒.这是可能的,还是我将被降级为创建一个元数据表,我为每个设备插入一个新行,然后使用它进行查询?
我试图通过partitionKey抽象来自Table的所有实体,如下所示:
public List<T> GetEntities<T>(string partitionKey, T entity) where T : TableEntity
{
try
{
var tableClient = _account.CreateCloudTableClient();
var table = tableClient.GetTableReference(entity.GetType().Name.ToLower());
var exQuery =
new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
partitionKey));
var results = table.ExecuteQuery(exQuery).Select(ent => (T) ent).ToList();
return results;
}
catch (StorageException ex)
{
//TODO: Add more trace info
Trace.TraceInformation("Unable to retrieve entity based on query specs");
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,它失败了
new TableQuery<T>
Run Code Online (Sandbox Code Playgroud)
因为TElement没有无参数构造函数.
这是我第一次使用Azure Storage Explorer,我需要阅读一些保存在Azure Tables中的日志.我的版本是4
我阅读此参考http://msdn.microsoft.com/library/azure/ff683669.aspx但没有解释使用列Timestamp.
基本上,我希望从特定日期开始查看日志.
我试过像查询;
时间戳ge'4/10/2013'Timestamp ge 4/10/2013时间戳gt'4/10/
2013'Timestamp gt 4/10/2013
结果只是一条错误信息.
处理此请求时发生错误.
我有一个Azure表,客户发布消息,单个表中可能有数百万条消息.我想找到最快的方式来获取最近10分钟内发布的消息(这是我刷新网页的频率).由于只对分区键编制索引,因此我使用了将消息作为分区键发布的日期和时间的想法,例如字符串作为ISO8601日期格式,如"2009-06-15T13:45:30.0900000"
伪代码示例:
var message = "Hello word!";
var messagePartitionKey = DateTime.Now.ToString("o");
var messageEntity = new MessageEntity(messagePartitionKey, message);
dataSource.Insert(messageEntity);
Run Code Online (Sandbox Code Playgroud)
,然后查询最近10分钟内发布的消息,如下所示(未经测试的伪代码):
// Get the date and time 10 minutes ago
var tenMinutesAgo = DateTime.Now.Subtract(new TimeSpan(0, 10, 0)).ToString("o");
// Query for the latest messages
var latestMessages = (from t in
context.Messages
where t.PartitionKey.CompareTo(tenMinutesAgo) <= 0
select t
)
Run Code Online (Sandbox Code Playgroud)
但这个指数会很好吗?或者它会导致全表扫描?有人有更好的想法吗?我知道每个表项都有一个时间戳,但它没有编入索引,所以它对我来说太慢了.
我正在尝试查询Windows Azure存储中的表,并且最初TableQuery.CombineFilters在TableQuery<RecordEntity>().Where函数中使用如下:
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.GreaterThanOrEqual, lowDate),
TableOperators.And,
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.LessThanOrEqual, lowDate),
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, entityId)
));
Run Code Online (Sandbox Code Playgroud)
不幸的是,CombineFilters最多只允许2个查询条件.所以我现在正在这样做:
var tableQuery = new TableQuery<RecordRowEntity>()
.Where(TableQuery.CombineFilters("PartitionKey", string.Format("(PartitionKey ge '{0}') and (PartitionKey le '{1}') and (RowKey eq '{2}')", low, high, entityId));
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以做到这一点.我认为目前我正在这样做的方式很容易受到Azure Api工作方式的影响.
我正在尝试在PowerShell中实现SharedKeyLite授权头函数.这是连接到Azure Tables REST API.我遗漏了一些因为我一直收到错误:
服务器无法验证请求.确保正确形成Authorization标头的值,包括签名.
function GenerateHeader($accountName, $accountKey, $action)
{
$xmsdate = get-date
$xmsdate = $xmsdate.ToUniversalTime()
$xmsdate = $xmsdate.toString('r')
$newLine = "`n";
$message = $xmsdate + $newline + "/" + $accountname + "/" + $action;
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($message))
$signature = [Convert]::ToBase64String($signature)
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("x-ms-version", "2014-02-14")
$headers.Add("x-ms-date", $xmsdate)
$headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)
return $headers
}
Run Code Online (Sandbox Code Playgroud)
更新:这是调用此函数的代码.$ action变量设置为URI字符串.
$uriString = "https://$StorageAccountName.table.core.windows.net/Tables"
$headers = GenerateHeader $StorageAccountName $StorageAccountKey "Tables"
Invoke-RestMethod …Run Code Online (Sandbox Code Playgroud)