

# Uso del modelo de persistencia de objetos de .NET y DynamoDB
<a name="DotNetSDKHighLevel"></a>

El AWS SDK para .NET proporciona un modelo de persistencia de objetos que le permite mapear las clases en el cliente a una tabla de Amazon DynamoDB. A continuación, cada instancia de objeto se mapea a un elemento en las tablas correspondientes. Para guardar los objetos del lado del cliente en las tablas, el modelo de persistencia de objetos proporciona la clase `DynamoDBContext`, un punto de entrada a DynamoDB. Esta categoría le ofrece una conexión a DynamoDB y le permite obtener acceso a tablas, realizar diversas operaciones CRUD y ejecutar consultas.

El modelo de persistencia de objetos proporciona un conjunto de atributos para mapear las clases del lado del cliente a tablas, y las propiedades/campos a atributos de tabla.

**nota**  
El modelo de persistencia de objetos no proporciona una API para crear, actualizar o eliminar tablas. Solo ofrece operaciones de datos. Puede usar la API de bajo nivel AWS SDK para .NET para crear, actualizar y eliminar tablas.

En el ejemplo siguiente se muestra cómo funciona el modelo de persistencia de objetos. Comienza con la tabla `ProductCatalog`. Su clave principal es `Id`.

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

Suponga que tiene una clase `Book` con las propiedades `Title`, `ISBN` y `Authors`. Puede mapear la clase `Book` a la tabla `ProductCatalog` agregando los atributos definidos por el modelo de persistencia de objetos, como se muestra en el siguiente ejemplo de código C\$1.

**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; }
  }
```

En el ejemplo anterior, el atributo `DynamoDBTable` mapea la clase `Book` a la tabla `ProductCatalog`.

El modelo de persistencia de objetos admite el mapeo tanto explícito como predeterminado entre las propiedades de clase y los atributos de tabla.
+ **Mapeo explícito**: para mapear una propiedad a una clave principal, debe usar los atributos `DynamoDBHashKey` y `DynamoDBRangeKey` del modelo de persistencia de objetos. Además, en el caso de los atributos sin clave principal, si un nombre de propiedad de la clase y el atributo de tabla correspondiente al que desea mapearlo no son iguales, debe definir el mapeo agregando explícitamente el atributo `DynamoDBProperty`.

  En el ejemplo anterior, la propiedad `Id` se mapea a la clave principal con el mismo nombre y la propiedad `BookAuthors` se mapea al atributo `Authors` de la tabla `ProductCatalog`.
+ **Mapeo predeterminado**: de forma predeterminada, el modelo de persistencia de objetos mapea las propiedades de clase a los atributos con el mismo nombre de la tabla.

  En el ejemplo anterior, las propiedades `Title` e `ISBN` se mapean a los atributos del mismo nombre de la tabla `ProductCatalog`.

No tiene que mapear cada propiedad de clase. Puede identificar estas propiedades agregando el atributo `DynamoDBIgnore`. Al guardar una instancia de `Book` en la tabla, `DynamoDBContext` no incluye la propiedad `CoverPage`. Tampoco se devolverá esta propiedad cuando se recupere la instancia del libro.

Puede mapear propiedades de tipos primitivos de .NET, como int o string. También puede mapear cualquier tipo de datos arbitrarios, siempre y cuando proporcione un convertidor adecuado para mapear los datos arbitrarios a uno de los tipos de DynamoDB. Para obtener más información sobre cómo mapear tipos arbitrarios, consulte [Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md).

El modelo de persistencia de objetos admite el bloqueo optimista. Durante una operación de actualización, esto garantiza que se disponga de la última copia del elemento que se va a actualizar. Para obtener más información, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

Para obtener más información, consulte los siguientes temas.

**Topics**
+ [Tipos de datos compatibles](#DotNetDynamoDBContext.SupportedTypes)
+ [Atributos de DynamoDB del modelo de persistencia de objetos de .NET](DeclarativeTagsList.md)
+ [Clase DynamoDBContext del modelo de persistencia de objetos de .NET](DotNetDynamoDBContext.md)
+ [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md)
+ [Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md)

## Tipos de datos compatibles
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

El modelo de persistencia de objetos admite un conjunto de tipos de datos, colecciones y tipos de datos arbitrarios de .NET primitivos. El modelo admite los siguientes tipos de datos primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

El modelo de persistencia de objetos también admite los tipos de colección de .NET. `DynamoDBContext` puede convertir tipos de colección concretos y objetos CLR estándar (POCO, por sus siglas en inglés) simples.

En la tabla siguiente se resume el mapeo de los tipos de .NET anteriores a los tipos de DynamoDB.


****  

| Tipo de .NET primitivo | Tipo DynamoDB | 
| --- | --- | 
|  Todos los tipos de números  |  `N` (tipo Number)  | 
|  Todos los tipos de cadenas  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binary)   | 
| bool | N (tipo Number), 0 representa false (falso) y 1 representa true (verdadero). | 
| Tipos de colección | BS (tipo Binary Set), SS (tipo String Set) y NS (tipo Number Set) | 
| DateTime | S (tipo String). Los valores DateTime se almacenan como cadenas con formato ISO-8601. | 

El modelo de persistencia de objetos también admite los tipos de datos arbitrarios. Sin embargo, debe proporcionar el código de convertidor para mapear los tipos complejos a los tipos de DynamoDB.

**nota**  
Se admiten valores binarios vacíos.
Se admite la lectura de valores de cadena vacíos. Los valores de atributo de cadena vacíos se admiten dentro de los valores de atributo del tipo de conjunto de cadenas mientras se escribe en DynamoDB. Los valores de atributo de cadena vacíos del tipo de cadena y los valores de cadena vacíos contenidos en el tipo lista o mapa se eliminan de las solicitudes de escritura

# Atributos de DynamoDB del modelo de persistencia de objetos de .NET
<a name="DeclarativeTagsList"></a>

En esta sección se describen los atributos que ofrece el modelo de persistencia de objetos para que pueda mapear las clases y propiedades a tablas y atributos de DynamoDB.

**nota**  
En los atributos siguientes, solo son obligatorios `DynamoDBTable` y `DynamoDBHashKey`.

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

Mapea una propiedad de clase a la clave de partición de un índice secundario global. Use este atributo si necesita `Query` un índice secundario global.

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

Mapea una propiedad de clase a la clave de ordenación de un índice secundario global. Use este atributo si tiene que utilizar una operación `Query` en un índice secundario global y desea refinar los resultados mediante la clave de ordenación del índice.

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

Mapea una propiedad de clase a la clave de partición de la clave principal de la tabla. Los atributos de clave principal no pueden ser un tipo de colección.

En los siguientes ejemplos de código C\$1 se mapea la clase `Book` a la tabla `ProductCatalog` y la propiedad `Id` a la clave de partición de la clave principal de la tabla.

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

    // Additional properties go here.
}
```

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

Indica que la propiedad asociada debe pasarse por alto. Si no desea guardar ninguna de las propiedades de clase, puede agregar este atributo para indicar a `DynamoDBContext` que no incluya esta propiedad cuando guarde objetos en la tabla.

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

Mapea una propiedad de clase a la clave de ordenación de un índice secundario local. Use este atributo si tiene que utilizar una operación `Query` en un índice secundario local y desea refinar los resultados mediante la clave de ordenación del índice.

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

Mapea una propiedad de clase a un atributo de tabla. Si la propiedad de clase se mapea al atributo de tabla con el mismo nombre, no es preciso especificarlo. Sin embargo, si los nombres no son iguales, puede utilizar esta etiqueta para realizar el mapeo. En la siguiente instrucción de C\$1, `DynamoDBProperty` mapea la propiedad `BookAuthors` al atributo `Authors` de la tabla. 

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

`DynamoDBContext` utiliza esta información de mapeo para crear el atributo `Authors` al guardar datos de objetos en la tabla correspondiente.

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

Especifica un nombre alternativo para una propiedad de clase. Esto resulta útil si va a escribir un convertidor personalizado para mapear datos arbitrarios a una tabla de DynamoDB cuando el nombre de una propiedad de clase sea distinto del nombre del atributo de tabla.

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

Mapea una propiedad de clase a la clave de ordenación de la clave principal de la tabla. Si la tabla tiene una clave principal compuesta (clave de partición y clave de ordenación), entonces debe especificar ambos atributos, `DynamoDBHashKey` y `DynamoDBRangeKey`, en el mapeo de clase.

Por ejemplo, en el ejemplo de tabla `Reply`, la clave principal consta de la clave de partición `Id` y de la clave de ordenación `Replenishment`. En el siguiente ejemplo de código C\$1 se mapea la clase `Reply` a la tabla `Reply`. La definición de clase también indica que dos de sus propiedades se mapean a la clave principal.

```
[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 la tabla de destino de DynamoDB a la que se mapea la clase. Por ejemplo, en el siguiente ejemplo de código C\$1 se mapea la clase `Developer` a la tabla `People` de DynamoDB.

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

Este atributo se puede heredar o anular.
+ El atributo `DynamoDBTable` se puede heredar. En el ejemplo anterior, si agrega una nueva clase, `Lead`, que hereda de la clase `Developer`, también se mapea a la tabla `People`. Ambos objetos, `Developer` y `Lead`, se almacenan en la tabla `People`.
+ El atributo `DynamoDBTable` también se puede anular. En el siguiente ejemplo de código C\$1, la clase `Manager` hereda de la clase `Developer`. Sin embargo, la adición explícita del atributo `DynamoDBTable` mapea la clase a otra tabla (`Managers`).

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

 Puede agregar el parámetro opcional, `LowerCamelCaseProperties`, para solicitar que DynamoDB cambie a minúscula la primera letra del nombre de la propiedad cuando almacene los objetos en una tabla, como se muestra en el siguiente fragmento de código C\$1.

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

Al guardar instancias de la clase `Developer`, `DynamoDBContext` guarda la propiedad `DeveloperName` como `developerName`.

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

Identifica una propiedad de clase para almacenar el número de versión del elemento. Para obtener más información sobre el control de versiones, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

# Clase DynamoDBContext del modelo de persistencia de objetos de .NET
<a name="DotNetDynamoDBContext"></a>

La clase `DynamoDBContext` es el punto de entrada de la base de datos de Amazon DynamoDB. Proporciona conexión con DynamoDB y le permite acceder a los datos de diversas tablas, realizar distintas operaciones CRUD y ejecutar consultas. La clase `DynamoDBContext` proporciona los métodos siguientes.

**Topics**
+ [CreateMultiTableBatchGet](#w2aac17b9c21c23c39b7)
+ [CreateMultiTableBatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Eliminar](#w2aac17b9c21c23c39c15)
+ [Dispose](#w2aac17b9c21c23c39c17)
+ [ExecuteBatchGet](#w2aac17b9c21c23c39c19)
+ [ExecuteBatchWrite](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [GetTargetTable](#w2aac17b9c21c23c39c29)
+ [Cargar](#w2aac17b9c21c23c39c31)
+ [Consultar](#w2aac17b9c21c23c39c33)
+ [Save](#w2aac17b9c21c23c39c35)
+ [Examen](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Especificación de parámetros opcionales para DynamoDBContext](#OptionalConfigParams)

## CreateMultiTableBatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Crea un objeto `MultiTableBatchGet`, que consta de varios objetos `BatchGet` individuales. Cada uno de estos objetos `BatchGet` se puede usar para recuperar elementos de una sola tabla de DynamoDB.

Para recuperar elementos de una o varias tablas, utilice el método `ExecuteBatchGet` y pase el objeto `MultiTableBatchGet` como parámetro.

## CreateMultiTableBatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Crea un objeto `MultiTableBatchWrite`, que consta de varios objetos `BatchWrite` individuales. Cada uno de estos objetos `BatchWrite` se puede usar para escribir o eliminar elementos de una sola tabla de DynamoDB.

Para escribir en una o varias tablas, utilice el método `ExecuteBatchWrite` y pase el objeto `MultiTableBatchWrite` como parámetro.

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

Crea un objeto `BatchGet` que puede usar para recuperar varios elementos de una tabla. 

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

Crea un objeto `BatchWrite` que puede usar para colocar o eliminar varios elementos en una tabla. 

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

Elimina un elemento de la tabla. El método requiere la clave principal del elemento que se desea eliminar. Como parámetro de este método, puede proporcionar el valor de la clave principal o un objeto del lado del cliente que contenga un valor de clave .
+ Si especifica un objeto del lado del cliente como parámetro y ha habilitado el bloqueo optimista, la eliminación se llevará a cabo correctamente solo si las versiones del lado del cliente y del lado del servidor del objeto coinciden.
+ Si especifica únicamente el valor de clave principal como parámetro, la eliminación se llevará a cabo correctamente tanto si ha habilitado bloqueo optimista como si no.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `DeleteAsync` en su lugar.

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

Elimina todos los recursos administrados y no administrados.

## ExecuteBatchGet
<a name="w2aac17b9c21c23c39c19"></a>

Lee datos en una o varias tablas y procesa todos los objetos `BatchGet` de un objeto `MultiTableBatchGet`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ExecuteBatchGetAsync` en su lugar.

## ExecuteBatchWrite
<a name="w2aac17b9c21c23c39c21"></a>

Escribe o elimina datos en una o varias tablas y procesa todos los objetos `BatchWrite` de un objeto `MultiTableBatchWrite`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ExecuteBatchWriteAsync` en su lugar.

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

Dada una instancia de un objeto `Document`, el método `FromDocument` devuelve una instancia de una clase del lado del cliente.

Esto resulta útil si desea utilizar las clases del modelo de documento junto con el modelo de persistencia de objetos para realizar operaciones con datos. Para obtener más información sobre las clases del modelo de documentos que se proporcionan en AWS SDK para .NET, consulte [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md).

Supongamos que tiene un objeto `Document` denominado `doc` que contiene una representación de un elemento `Forum`. (Para saber cómo construir este objeto, consulte la descripción del método `ToDocument` más adelante en este tema). Puede utilizar `FromDocument` para recuperar el elemento `Forum` del `Document` como se muestra en el siguiente ejemplo de código C\$1.

**Example**  

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

**nota**  
Si el objeto `Document` implementa la interfaz `IEnumerable`, puede usar el método `FromDocuments` en su lugar. Esto le permitirá recorrer en iteración todas las instancias de la clase contenidas en `Document`.

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

Ejecuta una operación `Query` con los parámetros de la consulta definidos en un objeto `QueryOperationConfig`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `FromQueryAsync` en su lugar.

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

Ejecuta una operación `Scan` con los parámetros del análisis definidos en un objeto `ScanOperationConfig`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `FromScanAsync` en su lugar.

## GetTargetTable
<a name="w2aac17b9c21c23c39c29"></a>

Recupera la tabla de destino del tipo especificado. Esto resulta útil si va a escribir un convertidor personalizado para mapear datos arbitrarios a una tabla de DynamoDB y tiene que determinar qué tabla está asociada con un tipo de datos personalizado.

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

Recupera un elemento de una tabla. El método requiere solo la clave principal del elemento que se desea recuperar. 

De forma predeterminada, DynamoDB devuelve el elemento con valores que presentan consistencia final. Para obtener más información sobre el modelo de consistencia final, consulte [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).

El método `Load` o `LoadAsync` llama a la operación [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), que requiere que especifique la clave principal de la tabla. Como `GetItem` omite el parámetro `IndexName`, no puede cargar un elemento con la partición o la clave de clasificación de un índice. Por lo tanto, debe utilizar la clave principal de la tabla para cargar un elemento.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `LoadAsync` en su lugar. Para ver un ejemplo del uso del método `LoadAsync` para realizar operaciones CRUD de alto nivel en una tabla de DynamoDB, consulte el siguiente ejemplo.

```
    /// <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");
            }
        }
    }
```

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

Consulta una tabla basándose en los parámetros de consulta que haya proporcionado.

Solo se puede consultar una tabla si cuenta con una clave principal compuesta (una clave de partición y una clave de ordenación). Al realizar la consulta, debe especificar una clave de partición y una condición que se aplica a la clave de ordenación.

Supongamos que tenemos una clase `Reply` del lado del cliente mapeada a la tabla `Reply` de DynamoDB. En el siguiente ejemplo de código C\$1 se consulta la tabla `Reply` para buscar las respuestas de las conversaciones de un foro publicadas en los últimos 15 días. La tabla `Reply` tiene una clave principal cuya clave de partición es `Id` y cuya clave de ordenación es `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);
```

Devuelve una colección de objetos `Reply`. 

El método `Query` devuelve una colección `IEnumerable` de "carga diferida". Inicialmente devuelve una sola página de resultados y, a continuación, realiza una llamada de servicio para obtener la página siguiente si es necesario. Para obtener todos los elementos coincidentes, solo tiene que recorrer en iteración el `IEnumerable`.

Si la tabla tiene una clave principal simple (clave de partición), no puede usar el método `Query`. En su lugar, puede usar el método `Load` y proporcionar la clave de partición para recuperar el elemento.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `QueryAsync` en su lugar.

## Save
<a name="w2aac17b9c21c23c39c35"></a>

Guarda el objeto especificado en la tabla. Si la clave principal especificada en el objeto de entrada no existe en la tabla, el método agrega un nuevo elemento a la tabla. Si la clave principal sí está presente, el método actualiza el elemento.

Si ha configurado el bloqueo optimista, la actualización solo se llevará a cabo correctamente si las versiones del elemento del lado del cliente y del lado del servidor coinciden. Para obtener más información, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

**nota**  
Para ejecutar esta operación en segundo plano, use el método `SaveAsync` en su lugar.

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

Realiza un examen de toda la tabla. 

Puede filtrar el resultado del examen especificando una condición de examen. La condición se puede evaluar según cualesquiera atributos de la tabla. Supongamos que tenemos una clase `Book` del lado del cliente mapeada a la tabla `ProductCatalog` de DynamoDB. En el siguiente ejemplo de código C\$1 se examina la tabla y se devuelven solamente aquellos elementos de libro cuyo precio es menor que 0.

**Example**  

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

El método `Scan` devuelve una colección `IEnumerable` de "carga diferida". Inicialmente devuelve una sola página de resultados y, a continuación, realiza una llamada de servicio para obtener la página siguiente si es necesario. Para obtener todos los elementos coincidentes, solo tiene que recorrer en iteración la colección `IEnumerable`.

Por motivos de desempeño, debe consultar las tablas y evitar examinarlas.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ScanAsync` en su lugar.

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

Devuelve una instancia de la clase `Document` del modelo de documento de la instancia de clase. 

Esto resulta útil si desea utilizar las clases del modelo de documento junto con el modelo de persistencia de objetos para realizar operaciones con datos. Para obtener más información sobre las clases del modelo de documentos que se proporcionan en AWS SDK para .NET, consulte [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md). 

Supongamos que tenemos una clase del lado del cliente mapeada al ejemplo de tabla `Forum`. Puede usar una `DynamoDBContext` para obtener un elemento, como un objeto `Document`, de la tabla `Forum`, como se muestra en el siguiente ejemplo de código C\$1.

**Example**  

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

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

## Especificación de parámetros opcionales para DynamoDBContext
<a name="OptionalConfigParams"></a>

Cuando se utiliza el modelo de persistencia de objetos, es posible especificar los siguientes parámetros opcionales para la clase `DynamoDBContext`.
+ **`ConsistentRead`**: cuando se recuperan datos utilizando las operaciones `Load`, `Query` o `Scan`, es posible agregar este parámetro si se desea para solicitar los valores más recientes de los datos.
+ **`IgnoreNullValues`**: este parámetro informa a `DynamoDBContext` de que debe pasar por alto los valores null de los atributos durante una operación `Save`. Si este parámetro es false (o, si no se ha establecido), entonces un valor null se interpretará como una instrucción de eliminar el atributo de que se trate. 
+ **`SkipVersionCheck`**: este parámetro informa a `DynamoDBContext` de que no debe comparar las versiones al guardar o eliminar un elemento. Para obtener más información sobre el control de versiones, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix`—** antepone una cadena determinada a los nombres de todas las tablas. Si este parámetro es null (o si no se ha establecido), no se utilizará ningún prefijo.
+ `DynamoDBEntryConversion`: especifica el esquema de conversión que utiliza el cliente. Puede establecer este parámetro en la versión V1 o V2. V1 es la versión predeterminada.

  En función de la versión que establezca, el comportamiento de este parámetro cambia. Por ejemplo:
  + En V1, el tipo de datos `bool` se convierte al tipo numérico `N`, donde 0 representa falso y 1 representa verdadero. En V2, `bool` se convierte en `BOOL`.
  + En V2, las listas y las matrices no se agrupan con los HashSets. Las listas y las matrices de números, tipos basados en cadenas y tipos basados en binarios se convierten al tipo `L` (Lista), que se puede enviar vacío para actualizar una lista. A diferencia de V1, en la que no se envía una lista vacía por cable.

    En V1, los tipos de recopilaciones, como List, HashSet y matrices, se tratan de la misma manera. La lista, el HashSet y la matriz de números se convierten al tipo `NS` (conjunto de números). 

  El siguiente ejemplo establece la versión del esquema de conversión en V2, lo que cambia el comportamiento de conversión entre los tipos .NET y los tipos de datos de DynamoDB.

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

En los siguientes fragmentos de código C\$1 se crea un nuevo `DynamoDBContext` especificando dos de los parámetros opcionales anteriores, `ConsistentRead` y `SkipVersionCheck`.

**Example**  

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

`DynamoDBContext` incluye estos parámetros opcionales con cada solicitud que se envía utilizando este contexto. 

En lugar de establecer estos parámetros en el nivel de `DynamoDBContext`, puede especificarlos para las operaciones individuales que ejecute utilizando `DynamoDBContext`, como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo se carga un elemento de libro concreto. El método `Load` de `DynamoDBContext` especifica los parámetros opcionales `ConsistentRead` y `SkipVersionCheck`.

**Example**  

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

En este caso, `DynamoDBContext` incluye estos parámetros solo cuando se envía la solicitud `Get`.

# Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET
<a name="DynamoDBContext.VersionSupport"></a>

La compatibilidad del modelo de persistencia de objetos con el bloqueo optimista garantiza que la versión del elemento en la aplicación sea la misma que en el lado del servidor antes de actualizar o eliminar el elemento. Supongamos que recupera un elemento para actualizarlo. Sin embargo, antes de que se devuelvan las actualizaciones, otra aplicación actualiza el mismo elemento. Ahora, su aplicación tiene una copia anticuada del elemento. Sin el bloqueo optimista, cualquier actualización que lleve a cabo sobrescribirá la actualización efectuada por la otra aplicación. 

La característica de bloqueo optimista del modelo de persistencia de objetos proporciona la etiqueta `DynamoDBVersion`, que se puede usar para habilitar el bloqueo optimista. Para utilizar esta característica, se agrega una propiedad a la clase para almacenar el número de versión. Agregue el atributo `DynamoDBVersion` a la propiedad. La primera vez que se guarda el objeto, `DynamoDBContext` asigna un número de versión e incrementa este valor cada vez que se actualiza el elemento. 

Su solicitud de actualización o eliminación solamente se llevará a cabo si la versión del objeto en el lado del cliente coincide con el número de versión del elemento correspondiente en el lado del servidor. Si su aplicación contiene una copia anticuada, debe obtener la versión más reciente del servidor para poder actualizar o eliminar el elemento en cuestión.

En el siguiente ejemplo de código C\$1 se define una clase `Book` con atributos de persistencia de objetos que la mapean a la tabla `ProductCatalog`. La propiedad `VersionNumber` de la clase asociada con el atributo `DynamoDBVersion` almacena el valor del número de versión.

**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**  
Puede aplicar el atributo `DynamoDBVersion` solamente a un tipo numérico primitivo que pueda contener valores null (por ejemplo, `int?`). 

El bloqueo optimista afecta a las operaciones de `DynamoDBContext` como se indica a continuación:
+ Para un elemento nuevo, `DynamoDBContext` asigna el número de versión inicial 0. Si recupera un elemento, actualiza una o varias de sus propiedades e intenta guardar los cambios, la operación de almacenamiento solamente se lleva a cabo si el número de versión del lado del cliente coincide con el número de versión del lado del servidor. `DynamoDBContext` aumenta el número de versión. No es necesario establecer el número de versión.
+ El método `Delete` proporciona sobrecargas que pueden tomar un valor de clave principal o un objeto como parámetro, como se muestra en el siguiente ejemplo de código C\$1.  
**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);
  ```

  Si proporciona un objeto como parámetro, la eliminación solamente se llevará a cabo si la versión del objeto coincide con el número de versión del elemento correspondiente en el lado del servidor. Sin embargo, si proporciona un valor de clave principal como parámetro, `DynamoDBContext` no detectará los números de versión y eliminará el elemento sin comprobar la versión. 

  Tenga en cuenta que la implementación interna del bloqueo optimista en el código del modelo de persistencia de objetos utiliza las acciones de actualización condicional y eliminación condicional del API de DynamoDB.

## Deshabilitación del bloqueo positivo
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Para deshabilitar el bloqueo optimista, se usa la propiedad de configuración `SkipVersionCheck`. Puede establecer esta propiedad al crear `DynamoDBContext`. En este caso, el bloqueo optimista está deshabilitado para todas las solicitudes que se realicen utilizando el contexto. Para obtener más información, consulte [Especificación de parámetros opcionales para DynamoDBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

En lugar de establecer la propiedad para todo el contexto, puede deshabilitar el bloqueo optimista para una operación específica, tal y como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo de código se utiliza el contexto para eliminar un elemento de libro. El método `Delete` establece la propiedad `SkipVersionCheck` opcional en true, con lo que deshabilita la comprobación de versiones.

**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 });
```

# Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Además de los tipos de .NET admitidos (consulte [Tipos de datos compatibles](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), puede utilizar tipos de la aplicación para los cuales no exista un mapeo directo a los tipos de Amazon DynamoDB. El modelo de persistencia de objetos es compatible con el almacenamiento de datos de tipos arbitrarios, siempre y cuando se proporcione el convertidor requerido para convertir los datos del tipo arbitrario al tipo de DynamoDB y viceversa. El código del convertidor transforma los datos tanto al guardar como al cargar los objetos.

Puede crear cualquier tipo en el lado del cliente. Sin embargo, los datos almacenados en las tablas serán de uno de los tipos de DynamoDB. Además, durante las consultas y los exámenes, las comparaciones se harán respecto a los datos almacenados en DynamoDB.

En el siguiente ejemplo de código C\$1 se define una clase `Book` con las propiedades `Id`, `Title`, `ISBN` y `Dimension`. La propiedad `Dimension` es del tipo `DimensionType`, que describe las propiedades `Height`, `Width` y `Thickness`. En el ejemplo de código se proporcionan los métodos de convertidor `ToEntry` y `FromEntry` para convertir los datos entre el tipo `DimensionType` y el tipo String de DynamoDB. Por ejemplo, al,x guardar una instancia `Book`, el convertidor crea una cadena `Dimension` de libro tal como “8,5x11x0,05”. Cuando recupera un libro, convierte la cadena a una instancia `DimensionType`.

En el ejemplo se mapea el tipo `Book` a la tabla `ProductCatalog`. Guarda un ejemplo de instancia de `Book`, la recupera, actualiza sus dimensiones y vuelve a guardar `Book` una vez actualizado.



Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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;
        }
    }
}
```