Skip to content

CQRS CRUD Data

anton-martyniuk edited this page Oct 26, 2022 · 3 revisions

CQRS has the following Commands used for Create, Update and Delete data:

  • CreateEntityCommand
  • CreateEntitiesCommand
  • UpdateEntityCommand
  • UpdateEntitiesCommand
  • UpdateEntityByActionCommand
  • DeleteEntityCommand
  • DeleteEntitiesCommand
  • DeleteAndReturnEntityCommand

List of template parameters:

  • TEntityDto is a type of entity returned from the service
  • TId is a type of the entity's identifier (mainly primary key)

CQRS has the following Commands to create entities:

/// <summary>
/// The mediator command model that creates the new entity
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided entity is null</exception>
/// <exception cref="EntityAlreadyExistsException">Thrown if an entity already exists in the data store</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while saving the entity in the data store</exception>
/// <returns>Updated entity by the data store (primary key, for example)</returns>
public record CreateEntityCommand<TEntityDto>(TEntityDto Entity) : IRequest<TEntityDto>
    where TEntityDto : class

/// <summary>
/// The mediator command model that creates a list of new entities in the data store
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided list of entities is null</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while saving the entities in the data store</exception>
/// <returns>A list of updated entities by the data store (primary key, for example)</returns>
public record CreateEntitiesCommand<TEntityDto>(List<TEntityDto> Entities) : IRequest<List<TEntityDto>>
    where TEntityDto : class

Example:

// Create single entity
var createdEntity = await _mediator.Send(new CreateEntityCommand(
   new Airplane
   {
      Model = "Boeing 737-800",
      YearOfManufacture = 2022
   })
);

// Create multiple entities
var createdEntities = await _mediator.Send(new CreateEntitiesCommand(
   new List<Airplane>
   {
       new Airplane
       {
           Model = "Boeing 737-800",
           YearOfManufacture = 2022
       },
       new Airplane
       {
           Model = "Boeing 777-200ER",
           YearOfManufacture = 2021
       }
   })
);

CQRS has the following Commands to update entities:

/// <summary>
/// The mediator command model that updates the entity in the data store with the given entity id
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided id or entity is null</exception>
/// <exception cref="EntityNotFoundException">Thrown if an entity does not exist in the data store</exception>
/// <exception cref="EntityConcurrentUpdateException">If an entity concurrent update occurred</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while updating the entity in the data store</exception>
/// <returns>Updated entity</returns>
public record UpdateEntityCommand<TEntityDto, TId>(TId Id, TEntityDto Entity) : IRequest<TEntityDto>
    where TEntityDto : class
    where TId : IEquatable<TId>

/// <summary>
/// The mediator command model that Updates the list of entities in the data store with the given list of entities.<br/>
/// If all or some of entities were not found in the data store - no exception is thrown
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided list of entities is null or has no entities in the list</exception>
/// <exception cref="EntityConcurrentUpdateException">If an entity concurrent update occurred</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while updating the entities in the data store</exception>
/// <returns>List of updated entities</returns>
public record UpdateEntitiesCommand<TEntityDto>(List<TEntityDto> Entities) : IRequest<List<TEntityDto>>
    where TEntityDto : class

/// <summary>
/// The mediator command model that updates the entity in the data store with the given entity id
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided id or entity is null</exception>
/// <exception cref="EntityNotFoundException">Thrown if an entity does not exist in the data store</exception>
/// <exception cref="EntityConcurrentUpdateException">If an entity concurrent update occurred</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while updating the entity in the data store</exception>
/// <returns>Updated entity</returns>
public record UpdateEntityByActionCommand<TEntityDto, TId>(TId Id, Action<TEntityDto> UpdateAction) : IRequest<TEntityDto>
    where TEntityDto : class
    where TId : IEquatable<TId>

Example:

// Update single entity by id
var updatedEntity = await _mediator.Send(new UpdateEntityCommand(airplaneEntity.Id, airplaneEntity));

// Update single entity by an action
var updatedEntity = await _mediator.Send(new UpdateEntityByActionCommand((1, airplane =>
   {
       airplane.YearOfManufacture = 2020;
   })
);

// Update multiple entities
var updatedEntities = await _mediator.Send(new UpdateEntitiesCommand(airplaneEntities));

CQRS has the following Commands to delete entities:

/// <summary>
/// The mediator command model that deletes the entity in the data store with the given entity id.<br/>
/// This method does NOT query the entity from the data store before deletion
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided id is null</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while deleting the entity in the data store</exception>
/// <returns><see langword="true"/> if entity was deleted; otherwise, <see langword="false"/></returns>
public record DeleteEntityCommand<TId>(TId Id) : IRequest<bool>
    where TId : IEquatable<TId>

/// <summary>
/// The mediator command model that deletes the list of entities in the data store with the given list of entity ids.<br/>
/// This method does NOT query the entities from the data store before deletion.<br/>
/// If all or some of entities were not found in the data store - no exception is thrown
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided list of entities is null or has no entities in the list</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while deleting the entities in the data store</exception>
/// <returns><see langword="true"/> if all entities were deleted; otherwise, <see langword="false"/></returns>
public record DeleteEntitiesCommand<TId>(List<TId> Ids) : IRequest<bool>
    where TId : IEquatable<TId>

/// <summary>
/// The mediator command model that deletes and returns an entity in the data store with the given entity id.<br/>
/// This method queries the entity from the data store before deletion
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if provided id is null</exception>
/// <exception cref="EntityNotFoundException">Thrown if an entity does not exist in the data store</exception>
/// <exception cref="InternalErrorException">Thrown if an error occurred while deleting the entity in the data store</exception>
/// <returns>Deleted entity</returns>
public record DeleteAndReturnEntityCommand<TEntityDto, TId>(TId Id) : IRequest<TEntityDto>
    where TEntityDto : class
    where TId : IEquatable<TId>

Both DeleteEntityCommand and DeleteEntitiesCommand for deletion of single and multiple entities perform bulk delete and do not query entity(s) from the database.
DeleteAndReturnEntityCommand queries and returns deleted entity from the data store.

Example:

// Delete single entity by id
await _mediator.Send(new DeleteEntityCommand(1));

// Delete single entity by id and return it
var deletedEntity = await _mediator.Send(new DeleteAndReturnEntityCommand(1));

// Delete multiple entities by ids
await _mediator.Send(new DeleteEntitiesCommand(new List<int> { 1, 5, 10 }));
Clone this wiki locally