Ejercicio: creación de nuevos elementos

Completado

Recuerde que puede crear elementos dentro de un contenedor mediante el SDK de Azure Cosmos DB para .NET. Para este proyecto, el contenedor de productos contendrá los elementos product y los elementos category especiales para cada categoría. Hay dos casos que necesita gestionar en esta aplicación:

  • Si una categoría está vacía, es adecuado crear simplemente el elemento de esa categoría individualmente. No hay elementos de productos relacionados que crear.
  • Pero si una categoría incluye productos relacionados, tendrá que crear simultáneamente el elemento de categoría y los artículos de producto relacionados.

Ahora mismo, usted tiene dos requisitos clave:

  1. Crear un elemento individualmente como una sola operación
  2. Usar un lote transaccional para crear varios elementos relacionados

Illustration of icons indicating data being uploaded to the cloud.

Tras completar este ejercicio, el proyecto tendrá la lógica de crear elementos en un contenedor, ya sea individualmente o como lote.

Agregue un elemento individual a un contenedor

En Azure Cosmos DB, puede crear, reemplazar o actualizar/insertar (upsert) elementos en un contenedor. La creación de un elemento requiere que este tenga un identificador único. El reemplazo de un elemento requiere que este ya exista. La operación actualizar/insertar (upsert) es muy versátil, ya que comprueba el identificador único y, después, reemplaza o crea el elemento. Para este proyecto, necesita poder ejecutar la aplicación varias veces sin errores, lo que hace de upsert una clara opción. Para el primer elemento, se crea una categoría que no tenga ningún producto asociado. Aquí, se implementa una única operación actualizar/insertar (upsert) con una categoría creada manualmente.

  1. Abra de nuevo el archivo Program.cs.

  2. Cree una nueva instancia de Categoría denominada goggles con los siguientes valores:

    Propiedad Valor
    id ef7fa0f1-0e9d-4435-aaaf-a778179a94ad
    categoryId gear-snow-goggles
    Category goggles = new(
        Id: "ef7fa0f1-0e9d-4435-aaaf-a778179a94ad",
        CategoryId: "gear-snow-goggles"
    );
    
  3. Cree una nueva instancia PartitionKey con el mismo valor que la propiedad categoryId de la instancia Categoría que creó anteriormente.

    PartitionKey gogglesKey = new("gear-snow-goggles");
    
  4. Use el UpsertItemAsync método para crear o reemplazar el elemento que pasa un objeto a crear por el elemento y un valor de clave de partición.

    Category result = await container.UpsertItemAsync(goggles, gogglesKey);
    
  5. Imprima varias propiedades de result en la consola, entre ellas: el identificador único del elemento y el tipo del elemento.

    Console.WriteLine($"[New item created]:\t{result.Id}\t(Type: {result.Type})");
    
  6. Cree una nueva instancia de Categoría denominada helmets con los siguientes valores:

    Propiedad Valor
    id 91f79374-8611-4505-9c28-3bbbf1aa7df7
    categoryId gear-climb-helmets
    Category helmets = new(
        Id: "91f79374-8611-4505-9c28-3bbbf1aa7df7",
        CategoryId: "gear-climb-helmets"
    );
    
  7. Cree una nueva instancia PartitionKey con el mismo valor que la propiedad categoryId de la instancia Categoría que creó anteriormente.

    PartitionKey helmetsKey = new("gear-climb-helmets");
    
  8. Use el método UpsertItemAsync para crear o reemplazar el elemento. Pase un objeto a crear por el elemento y un valor de clave de partición. Devuelva un objeto de tipo ItemResponse<T>.

    ItemResponse<Category> response = await container.UpsertItemAsync(helmets, helmetsKey);
    
  9. Imprima varias propiedades de response en la consola, entre ellas: el identificador único del elemento subyacente, el tipo del elemento subyacente y la carga de solicitudes en unidades de solicitud por segundo (US/s).

    Console.WriteLine($"[New item created]:\t{response.Resource.Id}\t(Type: {response.Resource.Type})\t(RUs: {response.RequestCharge})");
    
  10. Guarde el archivo Program.cs.

Implementación de varias operaciones como un lote transaccional

Ahora considere un escenario en el que desea crear varios productos junto con una categoría. Si se crean los productos pero la categoría no existe, esos productos no son tan útiles. La creación de varios elementos es una situación en la que puede usar una transacción para agrupar varias operaciones "puntuales" para que todas se realicen correctamente o produzcan un error como una sola unidad cohesiva. Volviendo a nuestro escenario, necesitamos crear una categoría para tiendas de campaña con unos pocos productos de tiendas de campaña. Ya tenemos un solo elemento de categoría sin ningún elemento de producto. Deberíamos terminar con algo así:

Diagram of items in Azure Cosmos DB grouped by their partition key.

En esta sección, se crea un lote transaccional para crear conjuntamente la categoría tents y los productos relacionados.

  1. En Program.cs, cree una nueva instancia de Categoría denominada tents con los siguientes valores:

    Propiedad Valor
    id 5df21ec5-813c-423e-9ee9-1a2aaead0be4
    categoryId gear-camp-tents
    Category tents = new(
        Id: "5df21ec5-813c-423e-9ee9-1a2aaead0be4",
        CategoryId: "gear-camp-tents"
    );
    
  2. Cree cuatro instancias del tipo Producto con estos valores.

    Propiedad cirroa kuloar mammatin nimbolo
    Id e8dddee4-9f43-4d15-9b08-0d7f36adcac8 e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa f7653468-c4b8-47c9-97ff-451ee55f4fd5 6e3b7275-57d4-4418-914d-14d1baca0979
    CategoryId gear-camp-tents gear-camp-tents gear-camp-tents gear-camp-tents
    Nombre Cirroa Tent Kuloar Tent Mammatin Tent Nimbolo Tent
    Precio 490.00 530.00 0.00 330.00
    Archived false false true false
    Cantidad 15 8 0 35
    Product cirroa = new(
        Id: "e8dddee4-9f43-4d15-9b08-0d7f36adcac8",
        CategoryId: "gear-camp-tents"
    ){
        Name = "Cirroa Tent",
        Price = 490.00m,
        Archived = false,
        Quantity = 15
    };
    
    Product kuloar = new(
        Id: "e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa",
        CategoryId: "gear-camp-tents"
    ){
        Name = "Kuloar Tent",
        Price = 530.00m,
        Archived = false,
        Quantity = 8
    };
    
    Product mammatin = new(
        Id: "f7653468-c4b8-47c9-97ff-451ee55f4fd5",
        CategoryId: "gear-camp-tents"
    ){
        Name = "Mammatin Tent",
        Price = 0.00m,
        Archived = true,
        Quantity = 0
    };
    
    Product nimbolo = new(
        Id: "6e3b7275-57d4-4418-914d-14d1baca0979",
        CategoryId: "gear-camp-tents"
    ){
        Name = "Nimbolo Tent",
        Price = 330.00m,
        Archived = false,
        Quantity = 35
    };
    
  3. Ahora cree una nueva instancia PartitionKey con el valor gear-camp-tents.

    PartitionKey tentsKey = new("gear-camp-tents");
    
  4. Cree un nuevo lote transaccional limitado al valor de la clave de partición gear-camp-tents mediante el método CreateTransactionalBatch(PartitionKey). Con la sintaxis fluida, agregue cinco operaciones upsert para crear los elementos que necesitamos en nuestro contenedor para la categoría y todos los productos relacionados.

    TransactionalBatch batch = container.CreateTransactionalBatch(tentsKey)
        .UpsertItem<Category>(tents)
        .UpsertItem<Product>(cirroa)
        .UpsertItem<Product>(kuloar)
        .UpsertItem<Product>(mammatin)
        .UpsertItem<Product>(nimbolo);
    
  5. Envíe un mensaje a la consola para indicar que estamos iniciando una operación por lotes.

    Console.WriteLine("[Batch started]");
    
  6. Use el método TransactionalBatch.ExecuteAsync para ejecutar el lote y devolver un tipo de respuesta especial.

    using TransactionalBatchResponse batchResponse = await batch.ExecuteAsync();
    
  7. Con un bucle for, recorra en iteración todos los elementos de la respuesta. En primer lugar, convierta cada elemento al tipo TransactionalBatchOperationResult con la clase base Item como genérica. A continuación, imprima el identificador único y el tipo del objeto de respuesta.

    for (int i = 0; i < batchResponse.Count; i++)
    {
        TransactionalBatchOperationResult<Item> batchResult = batchResponse.GetOperationResultAtIndex<Item>(i);
        Console.WriteLine($"[New item created]:\t{batchResult.Resource.Id}\t(Type: {batchResult.Resource.Type})");
    }
    
  8. Envíe otro mensaje a la consola que indique que el lote está completo. Incluya en este mensaje la carga de solicitudes de todo el lote.

    Console.WriteLine($"[Batch completed]:\t(RUs: {batchResponse.RequestCharge})");
    
  9. Guarde el archivo Program.cs.

Comprobar el trabajo

La aplicación ahora crea varios elementos y está diseñada para ser lo suficientemente resistente como para ejecutarse varias veces sin causar una excepción. Aquí, se ejecuta la aplicación y se comprueba la salida de los identificadores únicos de cada uno de los seis elementos recién creados.

  1. Ejecución de la aplicación .NET en el terminal:

    dotnet run
    
  2. Observe la salida de la ejecución de la aplicación. La salida debe coincidir con el ejemplo siguiente:

    ...
    [New item created]:     ef7fa0f1-0e9d-4435-aaaf-a778179a94ad    (Type: Category)
    [New item created]:     91f79374-8611-4505-9c28-3bbbf1aa7df7    (Type: Category)        (RUs: 10.29)
    [Batch started]
    [New item created]:     5df21ec5-813c-423e-9ee9-1a2aaead0be4    (Type: Category)
    [New item created]:     e8dddee4-9f43-4d15-9b08-0d7f36adcac8    (Type: Product)
    [New item created]:     e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa    (Type: Product)
    [New item created]:     f7653468-c4b8-47c9-97ff-451ee55f4fd5    (Type: Product)
    [New item created]:     6e3b7275-57d4-4418-914d-14d1baca0979    (Type: Product)
    [Batch completed]:      (RUs: 36.76)
    

    Sugerencia

    Las US/s que se muestran en esta salida de ejemplo pueden variar en su caso.