

# Trabalhar com o modelo de persistência de objetos do .NET e o DynamoDB
<a name="DotNetSDKHighLevel"></a>

O AWS SDK para .NET fornece um modelo de persistência de objetos que permite mapear classes do cliente em tabelas do Amazon DynamoDB. Em seguida, cada instância de objeto é mapeada para um item nas tabelas correspondentes. Para salvar objetos no lado do cliente nas tabelas, o modelo de persistência de objetos fornece a classe `DynamoDBContext`, um ponto de entrada para o DynamoDB. Esta classe fornece uma conexão ao DynamoDB e permite que você acesse tabelas, execute várias operações CRUD e realize consultas.

O modelo de persistência de objetos fornece um conjunto de atributos para mapear classes no lado do cliente para tabelas e propriedades/campos para atributos de tabela.

**nota**  
O modelo de persistência de objetos não fornece uma API para criar, atualizar ou excluir tabelas. Ele fornece apenas operações de dados. É possível usar somente a API de baixo nível do AWS SDK para .NET para criar, atualizar e excluir tabelas.

O exemplo a seguir mostra como o modelo de persistência de objetos funciona. Ele começa com a tabela `ProductCatalog`. `Id` é a chave primária.

```
ProductCatalog(Id, ...)
```

Suponha que você tenha uma classe `Book` com propriedades `Title`, `ISBN` e `Authors`. É possível mapear a classe `Book` na tabela `ProductCatalog` adicionando os atributos definidos pelo modelo de persistência de objetos, conforme mostrado no trecho de código C\$1 a seguir.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]
    public int Id { get; set; }

    public string Title { get; set; }
    public int ISBN { get; set; }

    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }

    [DynamoDBIgnore]
    public string CoverPage { get; set; }
  }
```

No exemplo anterior, o atributo `DynamoDBTable` mapeia a classe `Book` na tabela `ProductCatalog`.

O modelo de persistência objeto oferece suporte a tipos de mapeamento explícito e padrão entre propriedades de classe e atributos de tabela.
+ **Mapeamento explícito**: para mapear uma propriedade em uma chave primária, você deve usar os atributos `DynamoDBHashKey` e `DynamoDBRangeKey` do modelo de persistência de objetos. Além disso, para os atributos de chave não primárias, se um nome de propriedade na sua classe e o atributo de tabela correspondente ao qual você deseja mapear não forem os mesmos, será necessário definir o mapeamento adicionando explicitamente o atributo `DynamoDBProperty`.

  No exemplo anterior, a propriedade `Id` é mapeada na chave primária com o mesmo nome, e a propriedade `BookAuthors` é mapeada no atributo `Authors` na tabela `ProductCatalog`.
+ **Mapeamento padrão — **por padrão, o modelo de persistência objeto mapeia as propriedades da classe para os atributos com o mesmo nome na tabela.

  No exemplo anterior, as propriedades `Title` e `ISBN` são mapeadas nos atributos com o mesmo nome na tabela `ProductCatalog`.

Não é necessário mapear cada propriedade de classe. Identifique essas propriedades adicionando o atributo `DynamoDBIgnore`. Quando você salva uma instância de `Book` na tabela, `DynamoDBContext` não inclui a propriedade `CoverPage`. Ele também não retorna essa propriedade quando você recupera a instância de livro.

É possível mapear propriedades de tipos primitivos do .NET, como int e string. Também é possível mapear qualquer tipo de dados arbitrário, desde que você forneça um conversor apropriado para mapear os dados arbitrários em um do tipos do DynamoDB. Para saber mais sobre o mapeamento de tipos arbitrários, consulte [Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md).

O modelo de persistência objetos oferece suporte a bloqueio otimista. Durante uma operação de atualização, isso garante que você tenha a cópia mais recente do item que está prestes a atualizar. Para obter mais informações, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

Para obter mais informações, consulte os tópicos abaixo:

**Topics**
+ [Tipos de dados compatíveis](#DotNetDynamoDBContext.SupportedTypes)
+ [Atributos do DynamoDB do modelo de persistência de objetos do .NET](DeclarativeTagsList.md)
+ [Classe DynamoDBContext do modelo de persistência de objetos do .NET](DotNetDynamoDBContext.md)
+ [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md)
+ [Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md)

## Tipos de dados compatíveis
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

O modelo de persistência de objetos oferece suporte a um conjunto de tipos de dados primitivos do .NET, coleções e tipos de dados arbitrários. O modelo é compatível com os seguintes tipos de dados primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

O modelo de persistência de objetos também oferece suporte aos tipos de coleção .NET. `DynamoDBContext` é capaz de converter tipos de coleção concretos e objetos CLR básicos (POCOs).

A tabela a seguir resume o mapeamento dos tipos .NET anteriores nos tipos do DynamoDB.


****  

| Tipo primitivo .NET | Tipo do DynamoDB | 
| --- | --- | 
|  Todos os tipos de número  |  `N` (tipo Número)  | 
|  Todos os tipos de string  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binário)   | 
| bool | N (tipo numérico), 0 representa false 1 representa true. | 
| Tipos de coleção | Tipo BS (conjunto binário), tipo SS (conjunto de strings) e tipo NS (conjunto de números) | 
| DateTime | S (tipo String). Os valores de DateTime são armazenados como strings formatadas em ISO-8601. | 

O modelo de persistência de objetos também oferece suporte a tipos de dados arbitrários. No entanto, você deve fornecer o código de conversor para mapear os tipos complexos em tipos do DynamoDB.

**nota**  
Valores binários vazios são compatíveis.
A leitura de valores string vazios é compatível. Os valores de atributos string vazios são compatíveis nos valores de atributos do tipo de conjunto string durante a gravação no DynamoDB. Os valores de atributos string vazios do tipo string e os valores string vazios contidos no tipo Lista ou Mapa são descartados das solicitações de gravação

# Atributos do DynamoDB do modelo de persistência de objetos do .NET
<a name="DeclarativeTagsList"></a>

Esta seção descreve os atributos oferecidos pelo modelo de persistência objetos para que você possa mapear suas classes e propriedades em tabelas e atributos do DynamoDB.

**nota**  
Nos seguintes atributos, apenas `DynamoDBTable` e `DynamoDBHashKey` são necessários.

## DynamoDBGlobalSecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

Mapeia uma propriedade de classe na chave de partição de um índice secundário global. Use esse atributo se você precisa realizar uma `Query` em um índice secundário global.

## DynamoDBGlobalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

Mapeia uma propriedade de classe na chave de classificação de um índice secundário global. Use esse atributo se você precisa realizar uma operação `Query` em um índice secundário global e deseja refinar seus resultados usando a chave de classificação de índice.

## DynamoDBHashKey
<a name="w2aac17b9c21c23c37c11"></a>

Mapeia uma propriedade de classe para a chave de partição da chave primária da tabela. Os atributos de chave primária não podem ser um tipo de coleção.

Os seguintes exemplos de código C\$1 mapeiam a classe `Book` na tabela `ProductCatalog` e a propriedade `Id` na chave de partição da chave primária da tabela.

```
[DynamoDBTable("ProductCatalog")]
public class Book 
{
    [DynamoDBHashKey]
    public int Id { get; set; }

    // Additional properties go here.
}
```

## DynamoDBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

Indica que a propriedade associada deve ser ignorada. Se não desejar salvar nenhuma das suas propriedades de classe, você poderá adicionar esse atributo para instruir `DynamoDBContext` a não incluir essa propriedade ao salvar objetos na tabela.

## DynamoDBLocalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

Mapeia uma propriedade de classe na chave de classificação de um índice secundário local. Use esse atributo se você precisa realizar uma operação `Query` em um índice secundário local e deseja refinar seus resultados usando a chave de classificação de índice.

## DynamoDBProperty
<a name="w2aac17b9c21c23c37c17"></a>

Mapeia uma propriedade de classe em um atributo de tabela. Se a propriedade de classe for mapeada em um atributo de tabela com o mesmo nome, não será necessário especificar esse atributo. No entanto, se os nomes não forem iguais, você poderá usar essa tag para fornecer o mapeamento. Na instrução C\$1 a seguir, `DynamoDBProperty` mapeia a propriedade `BookAuthors` no atributo `Authors` na tabela. 

```
[DynamoDBProperty("Authors")]
public List<string> BookAuthors { get; set; }
```

`DynamoDBContext` usa essas informações de mapeamento para criar o atributo `Authors` ao salvar dados de objetos na tabela correspondente.

## DynamoDBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

Especifica um nome alternativo para uma propriedade de classe. Isso é útil quando você está escrevendo um conversor personalizado para o mapeamento de dados arbitrários em uma tabela do DynamoDB na qual o nome de uma propriedade de classe é diferente de um atributo da tabela.

## DynamoDBRangeKey
<a name="w2aac17b9c21c23c37c21"></a>

Mapeia uma propriedade de classe na chave de classificação da chave primária da tabela. Se a tabela tiver uma chave primária composta (chave de partição e chave de classificação), você deverá especificar os atributos `DynamoDBHashKey` e `DynamoDBRangeKey` no seu mapeamento de classes.

Por exemplo, a tabela de exemplo `Reply` tem uma chave primária composta pela chave de partição `Id` e pela chave de classificação `Replenishment`. O exemplo de código C\$1 a seguir mapeia a classe `Reply` na tabela `Reply`. A definição de classe também indica que duas de suas propriedades são mapeadas para a chave primária.

```
[DynamoDBTable("Reply")]
public class Reply 
{
   [DynamoDBHashKey]
   public int ThreadId { get; set; }
   [DynamoDBRangeKey]
   public string Replenishment { get; set; }
   
   // Additional properties go here.
}
```

## DynamoDBTable
<a name="w2aac17b9c21c23c37c23"></a>

Identifica a tabela de destino do DynamoDB na qual a classe é mapeada. Por exemplo, o exemplo de código C\$1 a seguir mapeia a classe `Developer` na tabela `People` no DynamoDB.

```
[DynamoDBTable("People")]
public class Developer { ...}
```

Esse atributo pode ser herdado ou substituído.
+ O atributo `DynamoDBTable` pode ser herdado. No exemplo anterior, se você adicionar uma nova classe, `Lead`, que herda da classe `Developer`, ela também será mapeada na tabela `People`. Ambos os objetos `Developer` e `Lead` são armazenados na tabela `People`.
+ O atributo `DynamoDBTable` também pode ser sobrescrito. No exemplo de código C\$1 a seguir, a classe `Manager` herda da classe `Developer`. No entanto, a adição explícita do atributo `DynamoDBTable` mapeia a classe em outra tabela (`Managers`).

  ```
  [DynamoDBTable("Managers")]
  public class Manager : Developer { ...}
  ```

 É possível adicionar o parâmetro opcional, `LowerCamelCaseProperties`, para solicitar que o DynamoDB coloque em minúscula a primeira letra do nome da propriedade ao armazenar os objetos em uma tabela, conforme mostrado no exemplo de código C\$1 a seguir.

```
[DynamoDBTable("People", LowerCamelCaseProperties=true)]
public class Developer 
{
    string DeveloperName;
    ...
}
```

Ao salvar as instâncias da classe `Developer`, `DynamoDBContext` salva a propriedade `DeveloperName` como `developerName`.

## DynamoDBVersion
<a name="w2aac17b9c21c23c37c25"></a>

Identifica uma propriedade de classe para armazenar o número de versão do item. Para obter mais informações sobre versionamento, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

# Classe DynamoDBContext do modelo de persistência de objetos do .NET
<a name="DotNetDynamoDBContext"></a>

A classe `DynamoDBContext` é o ponto de entrada para do banco de dados do Amazon DynamoDB. Ela fornece uma conexão com o DynamoDB e permite que você acesse seus dados em várias tabelas, realize várias operações CRUD e execute consultas. A classe `DynamoDBContext` fornece os seguintes métodos:

**Topics**
+ [Create​MultiTable​BatchGet](#w2aac17b9c21c23c39b7)
+ [Create​MultiTable​BatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Excluir](#w2aac17b9c21c23c39c15)
+ [Descartar](#w2aac17b9c21c23c39c17)
+ [Execute​Batch​Get](#w2aac17b9c21c23c39c19)
+ [Execute​Batch​Write](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [Get​Target​Table](#w2aac17b9c21c23c39c29)
+ [Carregar](#w2aac17b9c21c23c39c31)
+ [Consulta](#w2aac17b9c21c23c39c33)
+ [Save (Salvar)](#w2aac17b9c21c23c39c35)
+ [Verificar](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Especificar parâmetros opcionais para DynamoDBContext](#OptionalConfigParams)

## Create​MultiTable​BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Cria um objeto `MultiTableBatchGet` formado por vários objetos `BatchGet` individuais. Cada um desses objetos `BatchGet` pode ser usado para recuperar itens de uma única tabela do DynamoDB.

Para recuperar os itens das tabelas, use o método `ExecuteBatchGet`, passando o objeto `MultiTableBatchGet` como um parâmetro.

## Create​MultiTable​BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Cria um objeto `MultiTableBatchWrite` formado por vários objetos `BatchWrite` individuais. Cada um desses objetos `BatchWrite` pode ser usado para gravar ou excluir itens em uma única tabela do DynamoDB.

Para gravar nas tabelas, use o método `ExecuteBatchWrite`, passando o objeto `MultiTableBatchWrite` como um parâmetro.

## CreateBatchGet
<a name="w2aac17b9c21c23c39c11"></a>

Cria um objeto `BatchGet` que você pode usar para recuperar vários itens de uma tabela. 

## CreateBatchWrite
<a name="w2aac17b9c21c23c39c13"></a>

Cria um objeto `BatchWrite` que você pode usar para inserir vários itens em uma tabela ou para excluir vários itens de uma tabela. 

## Excluir
<a name="w2aac17b9c21c23c39c15"></a>

Exclui um item da tabela. O método requer a chave primária do item que você deseja excluir. É possível fornecer o valor da chave primária ou um objeto no lado do cliente que contém um valor de chave primária como um parâmetro para esse método.
+ Se você especificar um objeto no lado do cliente como um parâmetro e tiver habilitado o bloqueio otimista, a exclusão apenas será bem-sucedida se as versões no lado do cliente e no lado do servidor desse objeto corresponderem.
+ Se você especificar somente o valor da chave primária como parâmetro, a exclusão será bem-sucedida, independentemente de você ter habilitado ou não o bloqueio otimista.

**nota**  
Para realizar essa operação em segundo plano, use o método `DeleteAsync` em vez disso.

## Descartar
<a name="w2aac17b9c21c23c39c17"></a>

Descarta todos os recursos gerenciados e não gerenciados.

## Execute​Batch​Get
<a name="w2aac17b9c21c23c39c19"></a>

Lê dados de uma ou mais tabelas, processando todos os objetos `BatchGet` em um `MultiTableBatchGet`.

**nota**  
Para realizar essa operação em segundo plano, use o método `ExecuteBatchGetAsync` em vez disso.

## Execute​Batch​Write
<a name="w2aac17b9c21c23c39c21"></a>

Grava ou exclui dados em uma ou mais tabelas, processando todos os objetos `BatchWrite` em um `MultiTableBatchWrite`.

**nota**  
Para realizar essa operação em segundo plano, use o método `ExecuteBatchWriteAsync` em vez disso.

## FromDocument
<a name="w2aac17b9c21c23c39c23"></a>

Considerando uma instância de `Document`, o método `FromDocument` retorna uma instância de uma classe no lado do cliente.

Isso será útil se você quiser usar as classes de modelo de documento junto com o modelo de persistência de objetos para realizar qualquer operação de dados. Para obter mais informações sobre as classes do modelo de documento fornecidas pelo AWS SDK para .NET, consulte [Trabalhar com o modelo de documento do .NET no DynamoDB](DotNetSDKMidLevel.md).

Suponha que você tenha um objeto `Document` denominado `doc` que contém uma representação de um item `Forum`. (Para ver como construir esse objeto, consulte a descrição do método `ToDocument` mais adiante neste tópico.) Você pode usar `FromDocument` para recuperar o item `Forum` de `Document`, conforme mostrado no exemplo de código C\$1 a seguir.

**Example**  

```
forum101 = context.FromDocument<Forum>(101);
```

**nota**  
Se o objeto `Document` implementar a interface `IEnumerable`, você poderá usar o método `FromDocuments` em vez disso. Isso permite uma iteração sobre todas as instâncias da classe em `Document`.

## FromQuery
<a name="w2aac17b9c21c23c39c25"></a>

Executa uma operação `Query`, com os parâmetros de consulta definidos em um objeto `QueryOperationConfig`.

**nota**  
Para realizar essa operação em segundo plano, use o método `FromQueryAsync` em vez disso.

## FromScan
<a name="w2aac17b9c21c23c39c27"></a>

Executa uma operação `Scan`, com os parâmetros de verificação definidos em um objeto `ScanOperationConfig`.

**nota**  
Para realizar essa operação em segundo plano, use o método `FromScanAsync` em vez disso.

## Get​Target​Table
<a name="w2aac17b9c21c23c39c29"></a>

Recupera a tabela de destino para o tipo especificado. Isso é útil quando você está escrevendo um conversor personalizado para o mapeamento de dados arbitrários para uma tabela do DynamoDB e precisa determinar qual tabela está associada a um tipo de dados personalizado.

## Carregar
<a name="w2aac17b9c21c23c39c31"></a>

Recupera um item de uma tabela. O método requer somente a chave primária do item que você deseja recuperar. 

Por padrão, o DynamoDB retorna o item com valores finais consistentes. Para obter informações sobre o modelo final consistente, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

O método `Load` ou `LoadAsync` chama a operação [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), que exige que você especifique a chave primária para a tabela. Como `GetItem` ignora o parâmetro `IndexName`, você não pode carregar um item usando a partição ou a chave de classificação de um índice. Portanto, é necessário usar a chave primária da tabela para carregar um item.

**nota**  
Para realizar essa operação em segundo plano, use o método `LoadAsync` em vez disso. Para ver um exemplo do uso do método `LoadAsync` para realizar operações CRUD de alto nível em uma tabela do DynamoDB, consulte o exemplo a seguir.

```
    /// <summary>
    /// Shows how to perform high-level CRUD operations on an Amazon DynamoDB
    /// table.
    /// </summary>
    public class HighLevelItemCrud
    {
        public static async Task Main()
        {
            var client = new AmazonDynamoDBClient();
            DynamoDBContext context = new DynamoDBContext(client);
            await PerformCRUDOperations(context);
        }

        public static async Task PerformCRUDOperations(IDynamoDBContext context)
        {
            int bookId = 1001; // Some unique value.
            Book myBook = new Book
            {
                Id = bookId,
                Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
                Isbn = "111-1111111001",
                BookAuthors = new List<string> { "Author 1", "Author 2" },
            };

            // Save the book to the ProductCatalog table.
            await context.SaveAsync(myBook);

            // Retrieve the book from the ProductCatalog table.
            Book bookRetrieved = await context.LoadAsync<Book>(bookId);

            // Update some properties.
            bookRetrieved.Isbn = "222-2222221001";

            // Update existing authors list with the following values.
            bookRetrieved.BookAuthors = new List<string> { " Author 1", "Author x" };
            await context.SaveAsync(bookRetrieved);

            // Retrieve the updated book. This time, add the optional
            // ConsistentRead parameter using DynamoDBContextConfig object.
            await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            // Delete the book.
            await context.DeleteAsync<Book>(bookId);

            // Try to retrieve deleted book. It should return null.
            Book deletedBook = await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            if (deletedBook == null)
            {
                Console.WriteLine("Book is deleted");
            }
        }
    }
```

## Consulta
<a name="w2aac17b9c21c23c39c33"></a>

Consulta uma tabela com base em parâmetros de consulta que você fornece.

Você poderá consultar uma tabela somente se ela tiver uma chave primária composta (chave de partição e chave de classificação). Ao consultar, você deve especificar uma chave de partição e uma condição que se aplique à chave de classificação.

Suponha que você tenha uma classe `Reply` no lado do cliente mapeada na tabela `Reply` no DynamoDB. O exemplo de código C\$1 a seguir consulta a tabela `Reply` para encontrar respostas de tópicos de fórum postadas nos últimos 15 dias. A tabela `Reply` tem uma chave primária com a chave de partição `Id` e a chave de classificação `ReplyDateTime`.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

string replyId = "DynamoDB#DynamoDB Thread 1"; //Partition key
DateTime twoWeeksAgoDate = DateTime.UtcNow.Subtract(new TimeSpan(14, 0, 0, 0)); // Date to compare.
IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate);
```

Isso retorna uma coleção de objetos `Reply`. 

Por padrão, o método `Query` retorna uma coleção `IEnumerable` de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, você só precisa fazer uma iteração na coleção `IEnumerable`.

Se a sua tabela tiver uma chave primária simples (chave de partição), você não poderá usar o método `Query`. Em vez disso, poderá usar o método `Load` e fornecer a chave de partição para recuperar o item.

**nota**  
Para realizar essa operação em segundo plano, use o método `QueryAsync` em vez disso.

## Save (Salvar)
<a name="w2aac17b9c21c23c39c35"></a>

Salva o objeto especificado na tabela. Se a chave primária especificada no objeto de entrada não existir na tabela, o método adicionará um novo item à tabela. Se a chave primária existir, o método atualizará o item existente.

Se você tiver o bloqueio otimista configurado, a atualização será bem-sucedida apenas se as versões do item no lado do cliente e no lado do servidor corresponderem. Para obter mais informações, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

**nota**  
Para realizar essa operação em segundo plano, use o método `SaveAsync` em vez disso.

## Verificar
<a name="w2aac17b9c21c23c39c37"></a>

Realiza uma verificação de tabela inteira. 

Você pode filtrar o resultado da verificação especificando uma condição de verificação. A condição pode ser avaliada em qualquer atributo da tabela. Suponha que você tenha uma classe `Book` no lado do cliente mapeada na tabela `ProductCatalog` no DynamoDB. O exemplo de código C\$1 a seguir verifica a tabela e retorna apenas os itens de livro com preços inferiores a 0.

**Example**  

```
IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>(
                    new ScanCondition("Price", ScanOperator.LessThan, price),
                    new ScanCondition("ProductCategory", ScanOperator.Equal, "Book")
      );
```

Por padrão, o método `Scan` retorna uma coleção `IEnumerable` de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, basta fazer uma iteração na coleção `IEnumerable`.

Por motivos de performance, você deve consultar suas tabelas e evitar uma verificação de tabela.

**nota**  
Para realizar essa operação em segundo plano, use o método `ScanAsync` em vez disso.

## ToDocument
<a name="w2aac17b9c21c23c39c39"></a>

Retorna uma instância da classe de modelo de documento `Document` da sua instância de classe. 

Isso será útil se você quiser usar as classes de modelo de documento junto com o modelo de persistência de objetos para realizar qualquer operação de dados. Para obter mais informações sobre as classes do modelo de documento fornecidas pelo AWS SDK para .NET, consulte [Trabalhar com o modelo de documento do .NET no DynamoDB](DotNetSDKMidLevel.md). 

Suponha que você tenha uma classe de cliente mapeada na tabela de exemplo `Forum`. É possível usar um `DynamoDBContext` para obter um item, como um objeto `Document` da tabela `Forum`, conforme mostrado no exemplo de código C\$1 a seguir.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

Forum forum101 = context.Load<Forum>(101); // Retrieve a forum by primary key.
Document doc = context.ToDocument<Forum>(forum101);
```

## Especificar parâmetros opcionais para DynamoDBContext
<a name="OptionalConfigParams"></a>

Ao usar o modelo de persistência de objeto, você pode especificar os seguintes parâmetros opcionais para `DynamoDBContext`.
+ **`ConsistentRead`**: ao recuperar dados usando as operações `Load`, `Query` ou `Scan`, você pode opcionalmente adicionar esse parâmetro para solicitar os valores mais recentes dos dados.
+ **`IgnoreNullValues`**: esse parâmetro instrui `DynamoDBContext` a ignorar valores nulos em atributos durante uma operação `Save`. Se esse parâmetro for false (ou se não estiver definido), um valor nulo será interpretado como uma diretiva para excluir o atributo específico. 
+ **`SkipVersionCheck`**: esse parâmetro instrui o `DynamoDBContext` a não comparar versões ao salvar ou excluir um item. Para obter mais informações sobre versionamento, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix`—** prefixa todos os nomes de tabelas com uma string específica. Se esse parâmetro for nulo (ou se não estiver definido), nenhum prefixo será usado.
+ `DynamoDBEntryConversion`: especifica o esquema de conversão usado pelo cliente. Você pode definir esse parâmetro para a versão V1 ou V2. A versão padrão é V1.

  O comportamento desse parâmetro pode mudar com base na versão definida. Por exemplo:
  + Na V1, o tipo de dados `bool` é convertido no tipo numérico `N`, em que 0 representa falso e 1 representa verdadeiro. Na V2, `bool` é convertido em `BOOL`.
  + Na V2, listas e matrizes não são agrupadas com HashSets. Listas e matrizes de números, tipos baseados em strings e tipos baseados em binários são convertidos no tipo `L` (Lista), que pode ser enviado vazio para atualizar uma lista. Isso é diferente da V1, em que uma lista vazia não é enviada pela rede.

    Na V1, os tipos de coleção, como lista, HashSet e matrizes, são tratados da mesma forma. Lista, HashSet e matriz de números são convertidos no tipo `NS` (conjunto de números). 

  O exemplo a seguir define a versão do esquema de conversão como V2, o que altera o comportamento de conversão entre os tipos .NET e os tipos de dados do DynamoDB.

  ```
  var config = new DynamoDBContextConfig
  {
      Conversion = DynamoDBEntryConversion.V2
  };
  var contextV2 = new DynamoDBContext(client, config);
  ```

O exemplo de código C\$1 a seguir cria um `DynamoDBContext` especificando dois dos parâmetros opcionais anteriores, `ConsistentRead` e `SkipVersionCheck`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context =
       new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true});
```

`DynamoDBContext` inclui esses parâmetros opcionais com cada solicitação enviada usando esse contexto. 

Em vez de definir esses parâmetros no nível de `DynamoDBContext`, é possível especificá-los para operações individuais que você executa usando `DynamoDBContext`, conforme mostrado no exemplo de código C\$1 a seguir. O exemplo carrega um item de livro específico. O método `Load` de `DynamoDBContext` especifica os parâmetros `ConsistentRead` e `SkipVersionCheck` opcionais.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context = new DynamoDBContext(client);
Book bookItem = context.Load<Book>(productId,new DynamoDBContextConfig{ ConsistentRead = true, SkipVersionCheck = true });
```

Nesse caso, `DynamoDBContext` inclui esses parâmetros somente ao enviar a solicitação `Get`.

# Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET
<a name="DynamoDBContext.VersionSupport"></a>

O suporte para bloqueio otimista no modelo de persistência de objetos garante que a versão do item para a sua aplicação seja igual à versão do item no lado do servidor antes que esse item seja atualizado ou excluído. Suponha que você recupere um item para atualização. No entanto, antes de você retornar suas atualizações, outra aplicação atualiza o mesmo item. Agora, a aplicação tem uma cópia obsoleta do item. Sem o bloqueio otimista, qualquer atualização que você realizar substituirá a atualização feita pelo outro aplicativo. 

O recurso de bloqueio otimista do modelo de persistência de objetos fornece a tag `DynamoDBVersion` que você pode usar para habilitar o bloqueio otimista. Para usar esse recurso, adicione uma propriedade à sua classe para armazenar o número de versão. Você adiciona o atributo `DynamoDBVersion` à propriedade. Quando o objeto for salvo pela primeira vez, `DynamoDBContext` atribuirá um número de versão e incrementará esse valor cada vez que você atualizar o item. 

Sua solicitação de atualização ou exclusão só será bem-sucedida se a versão do objeto no lado do cliente corresponder ao número de versão correspondente do item no lado do servidor. Se a sua aplicação tiver uma cópia obsoleta, ela deverá obter a versão mais recente do servidor antes de poder atualizar ou excluir o item.

O exemplo de código C\$1 a seguir define uma classe `Book` com atributos de persistência de objetos mapeando-a na tabela `ProductCatalog`. A propriedade `VersionNumber` na classe decorada com o atributo `DynamoDBVersion` armazena o valor do número de versão.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]   //Partition key
    public int Id { get; set; }
    [DynamoDBProperty]
    public string Title { get; set; }
    [DynamoDBProperty]
    public string ISBN { get; set; }
    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }
    [DynamoDBVersion]
    public int? VersionNumber { get; set; }
  }
```

**nota**  
Você pode aplicar o atributo `DynamoDBVersion` apenas a um tipo primitivo numérico anulável (como `int?`). 

O bloqueio otimista tem o seguinte impacto sobre operações `DynamoDBContext`:
+ Para um novo item, `DynamoDBContext` atribui o número de versão inicial 0. Se você recuperar um item existente, atualizar uma ou mais das suas propriedades e tentar salvar as alterações, a operação de salvamento será bem-sucedida somente se o número de versão no lado do cliente e no lado do servidor corresponderem. `DynamoDBContext` incrementa o número de versão. Você não precisa definir o número de versão.
+ O método `Delete` fornece sobrecargas que podem usar um valor de chave primária ou um objeto como parâmetro, conforme mostrado no exemplo de código C\$1 a seguir.  
**Example**  

  ```
  DynamoDBContext context = new DynamoDBContext(client);
  ...
  // Load a book.
  Book book = context.Load<ProductCatalog>(111);
  // Do other operations.
  // Delete 1 - Pass in the book object.
  context.Delete<ProductCatalog>(book);
  
  // Delete 2 - Pass in the Id (primary key)
  context.Delete<ProductCatalog>(222);
  ```

  Se você fornecer um objeto como parâmetro, a exclusão apenas será bem-sucedida se a versão do objeto corresponder à versão de item no lado do servidor correspondente. No entanto, se você fornecer um valor de chave primária como parâmetro, `DynamoDBContext` desconhecerá qualquer número de versão e excluirá o item sem fazer a verificação de versão. 

  Observe que a implementação interna do bloqueio otimista no código do modelo de persistência de objetos usa as ações de API de atualização condicional e exclusão condicional no DynamoDB.

## Desabilitar o bloqueio positivo
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Para desabilitar o bloqueio otimista, use a propriedade de configuração `SkipVersionCheck`. Você pode definir essa propriedade ao criar . `DynamoDBContext`. Nesse caso, o bloqueio otimista está desabilitado para solicitações feitas usando o contexto. Para obter mais informações, consulte [Especificar parâmetros opcionais para DynamoDBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

Em vez de definir a propriedade no nível do contexto, você pode desabilitar o bloqueio otimista para uma operação específica, conforme mostrado no exemplo de código C\$1 a seguir. O exemplo de código usa o contexto para excluir um item de livro. O método `Delete` define a propriedade `SkipVersionCheck` opcional como true, desabilitando a verificação de versão.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);
// Load a book.
Book book = context.Load<ProductCatalog>(111);
...
// Delete the book.
context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true });
```

# Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Além dos tipos de .NET compatíveis (consulte [Tipos de dados compatíveis](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), é possível usar tipos em sua aplicação para os quais não há um mapeamento direto para os tipos do Amazon DynamoDB. O modelo de persistência de objetos oferece suporte ao armazenamento de dados de tipos arbitrários, desde que você forneça o conversor para converter dados do tipo arbitrário no tipo do DynamoDB e vice-versa. O código de conversor transforma os dados durante os processos de salvar e carregar os objetos.

É possível criar qualquer tipo no lado do cliente. No entanto, os dados armazenados nas tabelas são um dos tipos do DynamoDB e, durante a consulta e a verificação, qualquer comparação de dados feita baseia-se nos dados armazenados no DynamoDB.

O exemplo de código C\$1 a seguir define uma classe `Book` com as propriedades `Id`, `Title`, `ISBN` e `Dimension`. A propriedade `Dimension` é do `DimensionType`, que descreve as propriedades `Height`, `Width` e `Thickness`. O código de exemplo fornece os métodos de conversor `ToEntry` e `FromEntry` para converter dados entre o `DimensionType` e os tipos de string do DynamoDB. Por exemplo, ao salvar uma instância `Book`, o conversor cria uma string `Dimension` de livro como “8.5x11x.05". Quando você recupera um livro, ele converte a string em uma instância `DimensionType`.

O exemplo mapeia o tipo `Book` na tabela `ProductCatalog`. Ele salva uma instância `Book` de exemplo, recupera essa instância, atualiza suas dimensões e salva novamente o `Book` atualizado.



Para obter instruções passo a passo sobre como testar o exemplo a seguir, consulte [Exemplos de código .NET](CodeSamples.DotNet.md).

**Example**  

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

namespace com.amazonaws.codesamples
{
    class HighLevelMappingArbitraryData
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                DynamoDBContext context = new DynamoDBContext(client);

                // 1. Create a book.
                DimensionType myBookDimensions = new DimensionType()
                {
                    Length = 8M,
                    Height = 11M,
                    Thickness = 0.5M
                };

                Book myBook = new Book
                {
                    Id = 501,
                    Title = "AWS SDK for .NET Object Persistence Model Handling Arbitrary Data",
                    ISBN = "999-9999999999",
                    BookAuthors = new List<string> { "Author 1", "Author 2" },
                    Dimensions = myBookDimensions
                };

                context.Save(myBook);

                // 2. Retrieve the book.
                Book bookRetrieved = context.Load<Book>(501);

                // 3. Update property (book dimensions).
                bookRetrieved.Dimensions.Height += 1;
                bookRetrieved.Dimensions.Length += 1;
                bookRetrieved.Dimensions.Thickness += 0.2M;
                // Update the book.
                context.Save(bookRetrieved);

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }
    }
    [DynamoDBTable("ProductCatalog")]
    public class Book
    {
        [DynamoDBHashKey] //Partition key
        public int Id
        {
            get; set;
        }
        [DynamoDBProperty]
        public string Title
        {
            get; set;
        }
        [DynamoDBProperty]
        public string ISBN
        {
            get; set;
        }
        // Multi-valued (set type) attribute.
        [DynamoDBProperty("Authors")]
        public List<string> BookAuthors
        {
            get; set;
        }
        // Arbitrary type, with a converter to map it to DynamoDB type.
        [DynamoDBProperty(typeof(DimensionTypeConverter))]
        public DimensionType Dimensions
        {
            get; set;
        }
    }

    public class DimensionType
    {
        public decimal Length
        {
            get; set;
        }
        public decimal Height
        {
            get; set;
        }
        public decimal Thickness
        {
            get; set;
        }
    }

    // Converts the complex type DimensionType to string and vice-versa.
    public class DimensionTypeConverter : IPropertyConverter
    {
        public DynamoDBEntry ToEntry(object value)
        {
            DimensionType bookDimensions = value as DimensionType;
            if (bookDimensions == null) throw new ArgumentOutOfRangeException();

            string data = string.Format("{1}{0}{2}{0}{3}", " x ",
                            bookDimensions.Length, bookDimensions.Height, bookDimensions.Thickness);

            DynamoDBEntry entry = new Primitive
            {
                Value = data
            };
            return entry;
        }

        public object FromEntry(DynamoDBEntry entry)
        {
            Primitive primitive = entry as Primitive;
            if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value))
                throw new ArgumentOutOfRangeException();

            string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
            if (data.Length != 3) throw new ArgumentOutOfRangeException();

            DimensionType complexData = new DimensionType
            {
                Length = Convert.ToDecimal(data[0]),
                Height = Convert.ToDecimal(data[1]),
                Thickness = Convert.ToDecimal(data[2])
            };
            return complexData;
        }
    }
}
```