

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Utilizzo di indici secondari globali: .NET
<a name="GSILowLevelDotNet"></a>

Puoi utilizzare l'API di AWS SDK per .NET basso livello per creare una tabella Amazon DynamoDB con uno o più indici secondari globali, descrivere gli indici sulla tabella ed eseguire query utilizzando gli indici. Queste operazioni vengono mappate alle operazioni DynamoDB corrispondenti. Per ulteriori informazioni, consulta la [Documentazione di riferimento delle API di Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/). 

Di seguito sono riportate le operazioni comuni per le operazioni delle tabelle che utilizzano l'API di basso livello .NET. 

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. Fornisci i parametri obbligatori e facoltativi per l'operazione creando gli oggetti di richiesta corrispondenti.

   Ad esempio, creare un oggetto `CreateTableRequest` per creare una tabella e un oggetto `QueryRequest` per eseguire una query su una tabella o un indice. 

1. Eseguire il metodo appropriato fornito dal client creato nella fase precedente. 

**Topics**
+ [Creazione di una tabella con un indice secondario globale](#GSILowLevelDotNet.CreateTableWithIndex)
+ [Descrizione di una tabella con un indice secondario globale](#GSILowLevelDotNet.DescribeTableWithIndex)
+ [Esecuzione di query su un indice secondario globale](#GSILowLevelDotNet.QueryAnIndex)
+ [Esempio AWS SDK per .NET : indici secondari globali che utilizzano l'API di basso livello](GSILowLevelDotNet.Example.md)

## Creazione di una tabella con un indice secondario globale
<a name="GSILowLevelDotNet.CreateTableWithIndex"></a>

Puoi creare indici secondari globali al momento della creazione di una tabella. A tale scopo, utilizza `CreateTable` e fornisci le specifiche per uno o più indici secondari globali. Il seguente esempio di codice C\$1 crea una tabella per contenere le informazioni sui dati meteo. La chiave di partizione è `Location` e la chiave di ordinamento è `Date`. Un indice secondario globale denominato `PrecipIndex` consente di accedere rapidamente ai dati delle precipitazioni di vari luoghi.

Di seguito sono riportate le fasi per creare una tabella con un indice secondario globale, utilizzando l'API di basso livello di DynamoDB. 

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. Crea un'istanza della classe `CreateTableRequest` per fornire le informazioni della richiesta. 

   È necessario fornire il nome della tabella, la sua chiave primaria e i valori del throughput assegnato. Per l'indice secondario globale, è necessario fornire il nome dell'indice, le impostazioni di velocità effettiva assegnata, le definizioni degli attributi per la chiave di ordinamento dell'indice, lo schema della chiave per l'indice e la proiezione degli attributi.

1. Eseguire il metodo `CreateTable` fornendo l'oggetto della richiesta come parametro.

Il seguente esempio di codice C\$1 mostra le fasi precedenti. Il codice crea una tabella (`WeatherData`) con un indice secondario globale (`PrecipIndex`). La chiave di partizione dell'indice è `Date` e la sua chiave di ordinamento è `Precipitation`. Tutti gli attributi della tabella vengono proiettati nell'indice. Gli utenti possono eseguire query su questo indice per ottenere dati sul meteo di una data specifica, ordinando facoltativamente i dati per quantità di precipitazioni. 

Poiché `Precipitation` non è un attributo chiave per la tabella, non è obbligatorio. Tuttavia, item `WeatherData` senza `Precipitation` non vengono visualizzati in `PrecipIndex`.

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

// Attribute definitions
var attributeDefinitions = new List<AttributeDefinition>()
{
    {new AttributeDefinition{
        AttributeName = "Location",
        AttributeType = "S"}},
    {new AttributeDefinition{
        AttributeName = "Date",
        AttributeType = "S"}},
    {new AttributeDefinition(){
        AttributeName = "Precipitation",
        AttributeType = "N"}
    }
};

// Table key schema
var tableKeySchema = new List<KeySchemaElement>()
{
    {new KeySchemaElement {
        AttributeName = "Location",
        KeyType = "HASH"}},  //Partition key
    {new KeySchemaElement {
        AttributeName = "Date",
        KeyType = "RANGE"}  //Sort key
    }
};

// PrecipIndex
var precipIndex = new GlobalSecondaryIndex
{
    IndexName = "PrecipIndex",
    ProvisionedThroughput = new ProvisionedThroughput
    {
        ReadCapacityUnits = (long)10,
        WriteCapacityUnits = (long)1
    },
    Projection = new Projection { ProjectionType = "ALL" }
};

var indexKeySchema = new List<KeySchemaElement> {
    {new KeySchemaElement { AttributeName = "Date", KeyType = "HASH"}},  //Partition key
    {new KeySchemaElement{AttributeName = "Precipitation",KeyType = "RANGE"}}  //Sort key
};

precipIndex.KeySchema = indexKeySchema;

CreateTableRequest createTableRequest = new CreateTableRequest
{
    TableName = tableName,
    ProvisionedThroughput = new ProvisionedThroughput
    {
        ReadCapacityUnits = (long)5,
        WriteCapacityUnits = (long)1
    },
    AttributeDefinitions = attributeDefinitions,
    KeySchema = tableKeySchema,
    GlobalSecondaryIndexes = { precipIndex }
};

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

È necessario attendere fino a quando DynamoDB crea la tabella e imposta lo stato su `ACTIVE`. Dopodiché, puoi iniziare a inserire item di dati nella tabella.

## Descrizione di una tabella con un indice secondario globale
<a name="GSILowLevelDotNet.DescribeTableWithIndex"></a>

Per ottenere informazioni sugli indici secondari globali in una tabella, utilizza `DescribeTable`. Puoi accedere al nome, allo schema della chiave e agli attributi proiettati di ciascun indice.

Di seguito sono riportate le fasi per accedere alle informazioni dell'indice secondario globale per una tabella utilizzando l'API di basso livello .NET. 

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. Eseguire il metodo `describeTable` fornendo l'oggetto della richiesta come parametro.

   Crea un'istanza della classe `DescribeTableRequest` per fornire le informazioni della richiesta. Devi specificare il nome della tabella.

Il seguente esempio di codice C\$1 mostra le fasi precedenti.

**Example**  

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

DescribeTableResponse response = client.DescribeTable(new DescribeTableRequest { TableName = tableName});

List<GlobalSecondaryIndexDescription> globalSecondaryIndexes =
response.DescribeTableResult.Table.GlobalSecondaryIndexes;

// This code snippet will work for multiple indexes, even though
// there is only one index in this example.

foreach (GlobalSecondaryIndexDescription gsiDescription in globalSecondaryIndexes) {
     Console.WriteLine("Info for index " + gsiDescription.IndexName + ":");

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

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

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

## Esecuzione di query su un indice secondario globale
<a name="GSILowLevelDotNet.QueryAnIndex"></a>

È possibile utilizzare l'operazione `Query` su un indice secondario globale quasi nello stesso modo in cui si esegue una `Query` su una tabella. È necessario specificare il nome dell'indice, i criteri di query per la chiave di partizione e di ordinamento dell'indice (se presente) e gli attributi da restituire. In questo esempio, l'indice è `PrecipIndex`, avente una chiave di partizione `Date` e una chiave di ordinamento `Precipitation`. La query di indice restituisce tutti i dati sul meteo di una data specifica in cui le precipitazioni sono maggiori di zero.

Di seguito sono riportate le fasi per eseguire una query su un indice secondario globale utilizzando l'API di basso livello .NET. 

1. Creare un'istanza della classe `AmazonDynamoDBClient`.

1. Crea un'istanza della classe `QueryRequest` per fornire le informazioni della richiesta.

1. Eseguire il metodo `query` fornendo l'oggetto della richiesta come parametro.

Il nome di attributo `Date` è una parola riservata in DynamoDB. Pertanto, devi utilizzare un nome di attributo di espressione come segnaposto in `KeyConditionExpression`.

Il seguente esempio di codice C\$1 mostra le fasi precedenti.

**Example**  

```
client = new AmazonDynamoDBClient();

QueryRequest queryRequest = new QueryRequest
{
    TableName = "WeatherData",
    IndexName = "PrecipIndex",
    KeyConditionExpression = "#dt = :v_date and Precipitation > :v_precip",
    ExpressionAttributeNames = new Dictionary<String, String> {
        {"#dt", "Date"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
        {":v_date", new AttributeValue { S =  "2013-08-01" }},
        {":v_precip", new AttributeValue { N =  "0" }}
    },
    ScanIndexForward = true
};

var result = client.Query(queryRequest);

var items = result.Items;
foreach (var currentItem in items)
{
    foreach (string attr in currentItem.Keys)
    {
        Console.Write(attr + "---> ");
        if (attr == "Precipitation")
        {
            Console.WriteLine(currentItem[attr].N);
    }
    else
    {
        Console.WriteLine(currentItem[attr].S);
    }

         }
     Console.WriteLine();
}
```

# Esempio AWS SDK per .NET : indici secondari globali che utilizzano l'API di basso livello
<a name="GSILowLevelDotNet.Example"></a>

Il seguente esempio di codice C\$1 mostra come utilizzare gli indici secondari globali. L'esempio crea una tabella denominata `Issues`, che può essere utilizzata in un semplice sistema di tracciamento di bug per lo sviluppo di software. La chiave di partizione è `IssueId` e la chiave di ordinamento è `Title`. In questa tabella esistono tre indici secondari globali:
+ `CreateDateIndex`: la chiave di partizione è `CreateDate` e la chiave di ordinamento è `IssueId`. Oltre alle chiavi di tabella, vengono proiettati nell'indice gli attributi `Description` e `Status`.
+ `TitleIndex`: la chiave di partizione è `Title` e la chiave di ordinamento è `IssueId`. Non vengono proiettati nell'indice attributi diversi dalle chiavi di tabella.
+ `DueDateIndex`: la chiave di partizione è `DueDate`; non è presente una chiave di ordinamento. Tutti gli attributi della tabella vengono proiettati nell'indice.

Una volta creata la tabella `Issues`, il programma carica la tabella con i dati che rappresentano i report sui bug del software. Quindi esegue una query sui dati utilizzando gli indici secondari globali. Infine, il programma elimina la tabella `Issues`.

Per step-by-step istruzioni su come testare il seguente esempio, vedere. [Esempi di codice .NET](CodeSamples.DotNet.md)

**Example**  

```
using System;
using System.Collections.Generic;
using System.Linq;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class LowLevelGlobalSecondaryIndexExample
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();
        public static String tableName = "Issues";

        public static void Main(string[] args)
        {
            CreateTable();
            LoadData();

            QueryIndex("CreateDateIndex");
            QueryIndex("TitleIndex");
            QueryIndex("DueDateIndex");

            DeleteTable(tableName);

            Console.WriteLine("To continue, press enter");
            Console.Read();
        }

        private static void CreateTable()
        {
            // Attribute definitions
            var attributeDefinitions = new List<AttributeDefinition>()
        {
            {new AttributeDefinition {
                 AttributeName = "IssueId", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "Title", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "CreateDate", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "DueDate", AttributeType = "S"
             }}
        };

            // Key schema for table
            var tableKeySchema = new List<KeySchemaElement>() {
            {
                new KeySchemaElement {
                    AttributeName= "IssueId",
                    KeyType = "HASH" //Partition key
                }
            },
            {
                new KeySchemaElement {
                    AttributeName = "Title",
                    KeyType = "RANGE" //Sort key
                }
            }
        };

            // Initial provisioned throughput settings for the indexes
            var ptIndex = new ProvisionedThroughput
            {
                ReadCapacityUnits = 1L,
                WriteCapacityUnits = 1L
            };

            // CreateDateIndex
            var createDateIndex = new GlobalSecondaryIndex()
            {
                IndexName = "CreateDateIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "CreateDate", KeyType = "HASH" //Partition key
                },
                new KeySchemaElement {
                    AttributeName = "IssueId", KeyType = "RANGE" //Sort key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "INCLUDE",
                    NonKeyAttributes = {
                    "Description", "Status"
                }
                }
            };

            // TitleIndex
            var titleIndex = new GlobalSecondaryIndex()
            {
                IndexName = "TitleIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "Title", KeyType = "HASH" //Partition key
                },
                new KeySchemaElement {
                    AttributeName = "IssueId", KeyType = "RANGE" //Sort key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "KEYS_ONLY"
                }
            };

            // DueDateIndex
            var dueDateIndex = new GlobalSecondaryIndex()
            {
                IndexName = "DueDateIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "DueDate",
                    KeyType = "HASH" //Partition key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "ALL"
                }
            };



            var createTableRequest = new CreateTableRequest
            {
                TableName = tableName,
                ProvisionedThroughput = new ProvisionedThroughput
                {
                    ReadCapacityUnits = (long)1,
                    WriteCapacityUnits = (long)1
                },
                AttributeDefinitions = attributeDefinitions,
                KeySchema = tableKeySchema,
                GlobalSecondaryIndexes = {
                createDateIndex, titleIndex, dueDateIndex
            }
            };

            Console.WriteLine("Creating table " + tableName + "...");
            client.CreateTable(createTableRequest);

            WaitUntilTableReady(tableName);
        }

        private static void LoadData()
        {
            Console.WriteLine("Loading data into table " + tableName + "...");

            // IssueId, Title,
            // Description,
            // CreateDate, LastUpdateDate, DueDate,
            // Priority, Status

            putItem("A-101", "Compilation error",
                "Can't compile Project X - bad version number. What does this mean?",
                "2013-11-01", "2013-11-02", "2013-11-10",
                1, "Assigned");

            putItem("A-102", "Can't read data file",
                "The main data file is missing, or the permissions are incorrect",
                "2013-11-01", "2013-11-04", "2013-11-30",
                2, "In progress");

            putItem("A-103", "Test failure",
                "Functional test of Project X produces errors",
                "2013-11-01", "2013-11-02", "2013-11-10",
                1, "In progress");

            putItem("A-104", "Compilation error",
                "Variable 'messageCount' was not initialized.",
                "2013-11-15", "2013-11-16", "2013-11-30",
                3, "Assigned");

            putItem("A-105", "Network issue",
                "Can't ping IP address 127.0.0.1. Please fix this.",
                "2013-11-15", "2013-11-16", "2013-11-19",
                5, "Assigned");
        }

        private static void putItem(
            String issueId, String title,
            String description,
            String createDate, String lastUpdateDate, String dueDate,
            Int32 priority, String status)
        {
            Dictionary<String, AttributeValue> item = new Dictionary<string, AttributeValue>();

            item.Add("IssueId", new AttributeValue
            {
                S = issueId
            });
            item.Add("Title", new AttributeValue
            {
                S = title
            });
            item.Add("Description", new AttributeValue
            {
                S = description
            });
            item.Add("CreateDate", new AttributeValue
            {
                S = createDate
            });
            item.Add("LastUpdateDate", new AttributeValue
            {
                S = lastUpdateDate
            });
            item.Add("DueDate", new AttributeValue
            {
                S = dueDate
            });
            item.Add("Priority", new AttributeValue
            {
                N = priority.ToString()
            });
            item.Add("Status", new AttributeValue
            {
                S = status
            });

            try
            {
                client.PutItem(new PutItemRequest
                {
                    TableName = tableName,
                    Item = item
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void QueryIndex(string indexName)
        {
            Console.WriteLine
                ("\n***********************************************************\n");
            Console.WriteLine("Querying index " + indexName + "...");

            QueryRequest queryRequest = new QueryRequest
            {
                TableName = tableName,
                IndexName = indexName,
                ScanIndexForward = true
            };


            String keyConditionExpression;
            Dictionary<string, AttributeValue> expressionAttributeValues = new Dictionary<string, AttributeValue>();

            if (indexName == "CreateDateIndex")
            {
                Console.WriteLine("Issues filed on 2013-11-01\n");

                keyConditionExpression = "CreateDate = :v_date and begins_with(IssueId, :v_issue)";
                expressionAttributeValues.Add(":v_date", new AttributeValue
                {
                    S = "2013-11-01"
                });
                expressionAttributeValues.Add(":v_issue", new AttributeValue
                {
                    S = "A-"
                });
            }
            else if (indexName == "TitleIndex")
            {
                Console.WriteLine("Compilation errors\n");

                keyConditionExpression = "Title = :v_title and begins_with(IssueId, :v_issue)";
                expressionAttributeValues.Add(":v_title", new AttributeValue
                {
                    S = "Compilation error"
                });
                expressionAttributeValues.Add(":v_issue", new AttributeValue
                {
                    S = "A-"
                });

                // Select
                queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES";
            }
            else if (indexName == "DueDateIndex")
            {
                Console.WriteLine("Items that are due on 2013-11-30\n");

                keyConditionExpression = "DueDate = :v_date";
                expressionAttributeValues.Add(":v_date", new AttributeValue
                {
                    S = "2013-11-30"
                });

                // Select
                queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES";
            }
            else
            {
                Console.WriteLine("\nNo valid index name provided");
                return;
            }

            queryRequest.KeyConditionExpression = keyConditionExpression;
            queryRequest.ExpressionAttributeValues = expressionAttributeValues;

            var result = client.Query(queryRequest);
            var items = result.Items;
            foreach (var currentItem in items)
            {
                foreach (string attr in currentItem.Keys)
                {
                    if (attr == "Priority")
                    {
                        Console.WriteLine(attr + "---> " + currentItem[attr].N);
                    }
                    else
                    {
                        Console.WriteLine(attr + "---> " + currentItem[attr].S);
                    }
                }
                Console.WriteLine();
            }
        }

        private static void DeleteTable(string tableName)
        {
            Console.WriteLine("Deleting table " + tableName + "...");
            client.DeleteTable(new DeleteTableRequest
            {
                TableName = tableName
            });
            WaitForTableToBeDeleted(tableName);
        }

        private static void WaitUntilTableReady(string tableName)
        {
            string status = null;
            // Let us wait until table is created. Call DescribeTable.
            do
            {
                System.Threading.Thread.Sleep(5000); // Wait 5 seconds.
                try
                {
                    var res = client.DescribeTable(new DescribeTableRequest
                    {
                        TableName = tableName
                    });

                    Console.WriteLine("Table name: {0}, status: {1}",
                              res.Table.TableName,
                              res.Table.TableStatus);
                    status = res.Table.TableStatus;
                }
                catch (ResourceNotFoundException)
                {
                    // DescribeTable is eventually consistent. So you might
                    // get resource not found. So we handle the potential exception.
                }
            } while (status != "ACTIVE");
        }

        private static void WaitForTableToBeDeleted(string tableName)
        {
            bool tablePresent = true;

            while (tablePresent)
            {
                System.Threading.Thread.Sleep(5000); // Wait 5 seconds.
                try
                {
                    var res = client.DescribeTable(new DescribeTableRequest
                    {
                        TableName = tableName
                    });

                    Console.WriteLine("Table name: {0}, status: {1}",
                              res.Table.TableName,
                              res.Table.TableStatus);
                }
                catch (ResourceNotFoundException)
                {
                    tablePresent = false;
                }
            }
        }
    }
}
```