

# 处理本地二级索引：.NET
<a name="LSILowLevelDotNet"></a>

**Topics**
+ [创建具有本地二级索引的表](#LSILowLevelDotNet.CreateTableWithIndex)
+ [描述具有本地二级索引的表](#LSILowLevelDotNet.DescribeTableWithIndex)
+ [查询本地二级索引](#LSILowLevelDotNet.QueryAnIndex)
+ [示例：使用 适用于 .NET 的 AWS SDK 低级 API 的本地二级索引](LSILowLevelDotNet.Example.md)

您可以使用 适用于 .NET 的 AWS SDK 低级 API 创建具有一个或多个本地二级索引的 Amazon DynamoDB 表、描述表中的索引，以及使用索引执行查询。这些操作会映射到对应的低级 DynamoDB API 操作。有关更多信息，请参阅 [.NET 代码示例](CodeSamples.DotNet.md)。

以下是使用 .NET 低级 API 执行表操作的常见步骤。

1. 创建 `AmazonDynamoDBClient` 类的实例。

1. 通过创建对应的请求对象，为操作提供必需参数和可选参数。

   例如，创建一个 `CreateTableRequest` 数据元以创建表；创建一个 `QueryRequest` 数据元以查询表或索引。

1. 运行您在前面步骤中创建的客户端提供的适当方法。

## 创建具有本地二级索引的表
<a name="LSILowLevelDotNet.CreateTableWithIndex"></a>

本地二级索引必须在您创建表的同时创建。为此，请使用 `CreateTable` 并为一个或多个本地二级索引提供您的规范。以下 C\# 代码示例创建一个包含音乐精选中歌曲信息的表。分区键为 `Artist`，排序键为 `SongTitle`。`AlbumTitleIndex` 这一二级索引可以按专辑名称进行查询。

以下是使用 .NET 低级别 API 创建具有本地二级索引的表的步骤。

1. 创建 `AmazonDynamoDBClient` 类的实例。

1. 创建 `CreateTableRequest` 类实例，以提供请求信息。

   您必须提供表名称、主键以及预配置吞吐量值。对于本地二级索引，您必须提供索引名称、索引排序键的名称和数据类型、索引的键架构以及属性投影。

1. 以参数形式提供请求对象，运行 `CreateTable` 方法。

以下 C\# 代码示例演示了上述步骤。该代码创建表 (`Music`)，在 `AlbumTitle` 属性上具有二级索引。投影到索引的属性只有表的分区键、排序键以及索引排序键。

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "Music";

CreateTableRequest createTableRequest = new CreateTableRequest()
{
    TableName = tableName
};

//ProvisionedThroughput
createTableRequest.ProvisionedThroughput = new ProvisionedThroughput()
{
    ReadCapacityUnits = (long)5,
    WriteCapacityUnits = (long)5
};

//AttributeDefinitions
List<AttributeDefinition> attributeDefinitions = new List<AttributeDefinition>();

attributeDefinitions.Add(new AttributeDefinition()
{
    AttributeName = "Artist",
    AttributeType = "S"
});

attributeDefinitions.Add(new AttributeDefinition()
 {
     AttributeName = "SongTitle",
     AttributeType = "S"
 });

attributeDefinitions.Add(new AttributeDefinition()
 {
     AttributeName = "AlbumTitle",
     AttributeType = "S"
 });

createTableRequest.AttributeDefinitions = attributeDefinitions;

//KeySchema
List<KeySchemaElement> tableKeySchema = new List<KeySchemaElement>();

tableKeySchema.Add(new KeySchemaElement() { AttributeName = "Artist", KeyType = "HASH" });  //Partition key
tableKeySchema.Add(new KeySchemaElement() { AttributeName = "SongTitle", KeyType = "RANGE" });  //Sort key

createTableRequest.KeySchema = tableKeySchema;

List<KeySchemaElement> indexKeySchema = new List<KeySchemaElement>();
indexKeySchema.Add(new KeySchemaElement() { AttributeName = "Artist", KeyType = "HASH" });  //Partition key
indexKeySchema.Add(new KeySchemaElement() { AttributeName = "AlbumTitle", KeyType = "RANGE" });  //Sort key

Projection projection = new Projection() { ProjectionType = "INCLUDE" };

List<string> nonKeyAttributes = new List<string>();
nonKeyAttributes.Add("Genre");
nonKeyAttributes.Add("Year");
projection.NonKeyAttributes = nonKeyAttributes;

LocalSecondaryIndex localSecondaryIndex = new LocalSecondaryIndex()
{
    IndexName = "AlbumTitleIndex",
    KeySchema = indexKeySchema,
    Projection = projection
};

List<LocalSecondaryIndex> localSecondaryIndexes = new List<LocalSecondaryIndex>();
localSecondaryIndexes.Add(localSecondaryIndex);
createTableRequest.LocalSecondaryIndexes = localSecondaryIndexes;

CreateTableResponse result = client.CreateTable(createTableRequest);
Console.WriteLine(result.CreateTableResult.TableDescription.TableName);
Console.WriteLine(result.CreateTableResult.TableDescription.TableStatus);
```

您必须等待 DynamoDB 创建该表并将表的状态设置为 `ACTIVE`。然后，您就可以开始在表中添加数据项目。

## 描述具有本地二级索引的表
<a name="LSILowLevelDotNet.DescribeTableWithIndex"></a>

要获取表上有关本地二级索引的信息，请使用 `DescribeTable` API。对于每个索引，您都可以查看其名称、键架构和投影的属性。

以下介绍使用 .NET 低级 API 访问表中的本地二级索引信息的步骤。

1. 创建 `AmazonDynamoDBClient` 类的实例。

1. 创建 `DescribeTableRequest` 类实例，以提供请求信息。您必须提供表名称。

1. 以参数形式提供请求对象，运行 `describeTable` 方法。

以下 C\# 代码示例演示了上述步骤。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "Music";

DescribeTableResponse response = client.DescribeTable(new DescribeTableRequest() { TableName = tableName });
List<LocalSecondaryIndexDescription> localSecondaryIndexes =
    response.DescribeTableResult.Table.LocalSecondaryIndexes;

// This code snippet will work for multiple indexes, even though
// there is only one index in this example.
foreach (LocalSecondaryIndexDescription lsiDescription in localSecondaryIndexes)
{
    Console.WriteLine("Info for index " + lsiDescription.IndexName + ":");

    foreach (KeySchemaElement kse in lsiDescription.KeySchema)
    {
        Console.WriteLine("\t" + kse.AttributeName + ": key type is " + kse.KeyType);
    }

    Projection projection = lsiDescription.Projection;

    Console.WriteLine("\tThe projection type is: " + projection.ProjectionType);

    if (projection.ProjectionType.ToString().Equals("INCLUDE"))
    {
        Console.WriteLine("\t\tThe non-key projected attributes are:");

        foreach (String s in projection.NonKeyAttributes)
        {
            Console.WriteLine("\t\t" + s);
        }

    }
}
```

## 查询本地二级索引
<a name="LSILowLevelDotNet.QueryAnIndex"></a>

您可以对本地二级索引使用 `Query`，基本上与对表执行 `Query` 操作相同。您需要指定索引名称、索引排序键的查询条件以及要返回的属性。在本示例中，索引为 `AlbumTitleIndex`，索引排序键为 `AlbumTitle`。

要返回的只包含投影到索引的属性。您也可以修改此查询，让返回结果中也包含非键属性，但是这样会导致表抓取活动的成本相对较高的。有关表抓取的更多信息，请参阅 [属性投影](LSI.md#LSI.Projections)。

以下是使用 .NET 低级别 API 查询本地二级索引的步骤。

1. 创建 `AmazonDynamoDBClient` 类的实例。

1. 创建 `QueryRequest` 类实例，以提供请求信息。

1. 以参数形式提供请求对象，运行 `query` 方法。

以下 C\# 代码示例演示了上述步骤。

**Example**  

```
QueryRequest queryRequest = new QueryRequest
{
    TableName = "Music",
    IndexName = "AlbumTitleIndex",
    Select = "ALL_ATTRIBUTES",
    ScanIndexForward = true,
    KeyConditionExpression = "Artist = :v_artist and AlbumTitle = :v_title",
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":v_artist",new AttributeValue {S = "Acme Band"}},
        {":v_title",new AttributeValue {S = "Songs About Life"}}
    },
};

QueryResponse response = client.Query(queryRequest);

foreach (var attribs in response.Items)
{
    foreach (var attrib in attribs)
    {
        Console.WriteLine(attrib.Key + " ---> " + attrib.Value.S);
    }
    Console.WriteLine();
}
```