Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Azure表存储中使用整数行键?_C#_Azure_Azure Storage - Fatal编程技术网

C# 如何在Azure表存储中使用整数行键?

C# 如何在Azure表存储中使用整数行键?,c#,azure,azure-storage,C#,Azure,Azure Storage,我有连续编号的实体,我想在Azure表服务中保留这些实体,但是RowKey列的类型有问题。 实体的编号应该存储在RowKey列中,这样我可以快速查询实体(PK='..'&&RowKey=5),获取最新的实体(RowKey>10),并查询特定的实体集(RowKey>5&&RowKeye.ID>1&&e.ID

我有连续编号的实体,我想在Azure表服务中保留这些实体,但是RowKey列的类型有问题。 实体的编号应该存储在RowKey列中,这样我可以快速查询实体(
PK='..'&&RowKey=5
),获取最新的实体(
RowKey>10
),并查询特定的实体集(
RowKey>5&&RowKey<10

由于RowKey必须是字符串,低于比较值是有问题的(
“100”<“11”
)。 我考虑过在数字前加上零(因此
“100”>“011”
),但我无法预测实体的数量(因此也无法预测零的数量)

我知道我可以创建一个整数列,但是我会失去索引RowKey列的性能优势(另外,我没有任何其他适合RowKey的信息)。
以前有人遇到过这个问题吗?

您可以将guid后附加到整数。这应该有助于分类。

我通过创建一个自定义的
RowKey
类解决了这个问题,该类围绕一个字符串,并提供一个
增量
方法

我现在可以定义有效字符的范围(例如
0-9+a-z+a-z
)和该范围内的“计数”(例如
az9+1=aza
azZ+1=aA0
)。与仅使用数字相比,这种方法的优点是,我有更大范围的可能键(
62^n
,而不是
10^n

我仍然需要预先定义字符串的长度,不能更改它,但现在我可以存储几乎任意数量的实体,同时保持字符串本身更短。例如,我可以用10位数字存储
~8*10^17
键,用20位数字存储
~7*10^35

当然,可以进一步增加有效字符的数量,以便更有效地使用位数,但在我的例子中,上述范围已经足够,并且仍然足够可读,以便进行调试

我希望这个答案能帮助其他遇到同样问题的人


编辑:作为旁注,以防任何人想要实现类似的功能:您必须创建自定义字符范围,并且不能从0开始向上计数,因为数字(
0-9
)之间存在非法字符(例如
/
\
)和小写字母。

如果您使用

您将这样的内容添加到表格的模型中

public int ID 
{
    get
    {
        return int.Parse(RowKey);
    }
}
然后您可以在Linq查询中执行此操作

.Where(e => e.ID > 1 && e.ID < 10);
,其中(e=>e.ID>1&&e.ID<10);
使用这种技术,您实际上并没有向表中添加“ID”列,因为它没有“set”操作

我唯一不确定的是幕后到底发生了什么。我想知道Azure表存储查询的最终形式是什么样的,但我不确定如何找到答案。在调试和使用quickwatch时,我无法找到这些信息

更新


我还没有弄清楚到底发生了什么,但我有一种强烈的感觉,这不是很有效。我在想,要做的就是像OP一样创建一个。然后可以在Linq where子句中使用
RowKey.CompareTo()
函数按范围进行筛选

我找到了一个简单的方法,但是前面的解决方案更有效(关于密钥长度)。 我们不需要使用所有字母表,只需要使用数字,关键是使长度固定(0000000 10002,…):

公共类可读性:TableEntity
{
公共静态字符串KeyLength=“000000000000000”;
公共可读性(字符串分区ID,int-keyId)
{
this.PartitionKey=partitionId;
this.RowKey=keyId.ToString(KeyLength);
}
公众可读性()
{
}
}
公共IList Get(字符串partitionName、int-date、int-enddate)
{
CloudTableClient tableClient=storageAccount.CreateCloudTableClient();
//创建表示“人员”表的CloudTable对象。
CloudTable=tableClient.GetTableReference(“记录”);
//为所有客户实体构造查询操作,其中PartitionKey=“Smith”。
TableQuery=new TableQuery()。其中(TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,partitionName),
TableOperators.And,TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(“RowKey”、QueryComparisons.LessThan、enddate.ToString(ReadingEntity.KeyLength))、TableOperators和,
TableQuery.GenerateFilterCondition(“RowKey”,QueryComparisons.GreaterThanOrEqual,date.ToString(ReadingEntity.KeyLength'));
return table.ExecuteQuery.ToList();
}

希望这能有所帮助。

我也遇到了类似的问题,还有一个额外的警告,我还希望支持按降序排序行键。在我的例子中,我并不关心支持数以万亿计的可能值,因为我正确地使用了PartitionKey,并且在需要进一步分段RowKey时也使用了作用域前缀(如“scope id”->“12-8374”)

最后,我决定具体实施恩齐建议的一般方法。我使用了Base64编码的修改版本,生成了一个四个字符的字符串,它支持1600多万个值,可以按升序或降序排序。下面是代码,它已经过单元测试,但缺少范围检查/验证

//
///获取指定整数id的四个字符串表示形式。
/// 
///要转换的数字
///指示编码的数字将按升序还是降序排序
///数字的编码字符串表示形式
公共静态字符串NumberToId(整数,布尔升序=true)
{
如果(!升序)
编号=16777215-编号;
返回新字符串(新[]{
六位字符((字节)((数字
public class ReadingEntity : TableEntity
{
    public static string KeyLength = "000000000000000000000";
    public ReadingEntity(string partitionId, int keyId)
    {
        this.PartitionKey = partitionId;
        this.RowKey = keyId.ToString(KeyLength); ;


    }
    public ReadingEntity()
    {
    }
}


public IList<ReadingEntity> Get(string partitionName,int date,int enddate)
{
        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

        // Create the CloudTable object that represents the "people" table.
        CloudTable table = tableClient.GetTableReference("Record");

        // Construct the query operation for all customer entities where PartitionKey="Smith".
        TableQuery<ReadingEntity> query = new TableQuery<ReadingEntity>().Where(TableQuery.CombineFilters(
    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionName),
    TableOperators.And,TableQuery.CombineFilters(
    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, enddate.ToString(ReadingEntity.KeyLength)), TableOperators.And,
    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, date.ToString(ReadingEntity.KeyLength)))));
        return table.ExecuteQuery(query).ToList();
}