Esta série sobre CRUD do ASP.NET Core está chegando ao fim. Já cobrimos configuração (parte 1), Leitura com SQL++ (parte 2), leitura com valor-chave (parte 3)e Criação/atualização (parte 4). Nesta última postagem, daremos uma olhada no D em CRUD: exclusão.
Exclusão com SQL++ ou valor-chave
Esperamos que você esteja percebendo um padrão. Assim como na leitura, criação e atualização, você tem vários caminhos para a exclusão. Você pode usar um SQL++ DELETE declaração:
1 2 |
DELETE DE demonstração.Padrão.Lista de desejos w ONDE META(w).id = "1c3de2e7-70ea-4ee2-803b-425bbf6251cb" |
Ou você pode usar uma operação de exclusão de valor-chave (também conhecida como "Remover“):
1 |
aguardar coleção.RemoveAsync("1c3de2e7-70ea-4ee2-803b-425bbf6251cb"); |
E, como antes, aqui estão as diretrizes muito semelhantes para ajudá-lo a decidir qual delas usar:
Caso de uso | Chave-valor? | Por que ou por que não? |
Excluir um usuário com a chave "73892" | Sim | Acesso direto |
Excluir um grupo de usuários com as chaves "73892", "47212" e "90491" | Sim | Isso pode exigir várias operações de valor-chave, mas ainda assim pode ser mais rápido do que usar um SQL EXCLUIR ... ONDE ... EM consulta. |
Excluir todos os usuários de "Ohio" | Não | O estado do usuário é provavelmente um atributo "secundário", não uma chave (vários usuários podem ser de Ohio). Esse é um bom caso de uso para um SQL++ DELETE |
Um ponto de extremidade de exclusão para o ASP.NET Core
Com isso em mente, crie um endpoint de exclusão da seguinte forma:
1 2 3 4 5 6 7 8 9 10 11 |
[HttpDelete] [Rota("api/delete")] público assíncrono Tarefa<IActionResult> Excluir(Guia id) { var balde = aguardar _bucketProvider.GetBucketAsync("demo"); var coleção = aguardar balde.CollectionAsync("lista de desejos"); aguardar coleção.RemoveAsync(id.ToString()); retorno Ok(novo { sucesso = verdadeiro }); } |
Experimente esse endpoint com OpenAPI / Swagger e ele se comportará como você espera.
Devo realmente excluir?
Em muitos casos de uso, talvez você não queira de fato excluir dados. Talvez você queira fazer algo chamado de exclusão "suave". Isso envolve mover ou marcar os dados de forma que eles ainda existam no banco de dados, mas não sejam mais exibidos para o usuário final. Isso tem a vantagem de ser detectável, recuperável e reportável.
Também é uma ótima oportunidade para mostrar a flexibilidade de um banco de dados NoSQL JSON.
Exclusão suave
Vamos introduzir um campo "excluído" nos itens da lista de desejos. Esse campo conterá uma data/hora em que o item foi excluído. Se esse campo existir, o restante do ponto de extremidade deverá considerar esse item como excluído. No entanto, se necessário, ainda poderemos consultá-lo, gerar relatórios sobre ele e recuperá-lo.
Em um banco de dados relacional, isso provavelmente exigiria um ALTER. Dependendo do tamanho de seus dados, isso pode exigir algum tempo de inatividade ou possivelmente muitos valores NULL. Em um banco de dados JSON, não é necessário informar ao banco de dados nada sobre um novo campo.
Vamos usar o API do subdocumento para adicionar um "excluído" para o documento. Subdocumento significa que só operaremos em um porção do JSON e deixar o resto em paz.
1 2 3 4 5 6 7 8 9 10 11 12 |
[HttpDelete] [Rota("api/softDelete")] público assíncrono Tarefa<IActionResult> SoftDelete(Guia id) { var balde = aguardar _bucketProvider.GetBucketAsync("demo"); var coleção = aguardar balde.CollectionAsync("lista de desejos"); aguardar coleção.MutateInAsync(id.ToString(), opções => opções.Upsert("excluído", DateTime.Agora)); retorno Ok(novo { sucesso = verdadeiro }); } |
(Certifique-se de que usando Couchbase.KeyValue; está na parte superior de seu GiftsController arquivo).
Esse código envia um comando para o Couchbase: para o documento com tal e tal ID, insira um campo chamado "excluído" e forneça a data/hora atual como um valor.
Observe que, com o subdocumento, não precisamos carregar primeiro o documento existente e não precisamos enviar todo o documento modificado de volta pelo cabo.
Dados excluídos suavemente
O resultado final será um documento com a seguinte aparência:
1 2 3 4 |
{ "name" (nome): "Porta-retratos digital", "excluído": "2022-04-21T11:05:26.1766248-04:00" } |
Os outros documentos em minha lista de desejos têm não ter um excluído campo. Eles ainda se parecem:
1 2 3 |
{ "name" (nome): "Camiseta Skyline Chili 2XL" } |
e
1 2 3 |
{ "name" (nome): "Camisa de Joey Votto" } |
Observe que eles não têm um "deleted": nulo eles não têm um campo “excluído“ campo.
SELEÇÃO com exclusão suave
Os dados são marcado como excluído, mas ele ainda está no banco de dados. Precisamos modificar o Obter tudo ponto final (Consulte a parte 2 para saber mais sobre Obter tudo) para levar isso em conta:
1 2 3 |
SELECIONAR META(w).id, w.* DE demonstração.Padrão.Lista de desejos w ONDE w.excluído IS FALTANDO |
Introduzi mais algumas sintaxes do SQL++ aqui: FALTANDO. Esse é um conceito que não existe em bancos de dados relacionais. No banco de dados relacional, qualquer coluna especificada na consulta deve ser definida e deve ter um valor (mesmo que seja nulo). Com um banco de dados de documentos JSON NoSQL, não existe essa restrição.
Aprimorando o índice
Um último ponto a ser discutido é a indexação. Em Parte 2Na primeira vez que criamos um índice primário, apenas para começar. No entanto, esse índice raramente será o mais eficiente. Criação e ajuste de índices é um tópico profundo, assim como o é no mundo dos bancos de dados relacionais.
Felizmente, o Couchbase Capella tem um Aconselhar ferramenta que pode recomendar índices melhores. Basta clicar em Aconselhar no Query Workbench (ou você pode usar CONSELHO sintaxe).
Nesse caso, ele fornece a seguinte recomendação:
1 2 3 4 5 6 7 8 9 10 11 |
"recommended_indexes" (índices recomendados): { "indexes" (índices): [ { "index_statement" (declaração de índice): "CREATE INDEX adv_deletedISMISSING ON `default`:`demo`.`_default`.`wishlist`(`deleted` IS MISSING) WHERE `deleted` IS MISSING", "index_statement_relative": "CREATE INDEX adv_deletedISMISSING ON `wishlist`(`deleted` IS MISSING) WHERE `deleted` IS MISSING", "keyspace_alias": "wishlist_w", "query_context": "default:demo._default", "recommending_rule" (regra de recomendação): "As chaves de índice seguem a ordem dos tipos de predicado: 2. igualdade/nulo/ausência." } ] } |
No caso de nossa quantidade muito pequena de dados de lista de desejos, provavelmente não vale a pena criar esse índice. Entretanto, se estivéssemos gerenciando as listas de desejos de todo um site de comércio eletrônico (por exemplo), esse índice seria um bom ponto de partida.
O fim do CRUD
Chegamos ao fim da criação de um aplicativo ASP.NET Core CRUD muito simples com o Couchbase. A superfície final da API tem a seguinte aparência:
Aqui está um detalhamento dos conceitos desta série, com links para a documentação para se aprofundar:
-
- Configurando o Capella
- Configuração da injeção de dependência do .NET
- SQL++ (às vezes ainda chamado de "N1QL")
-
-
- Operações CRUD de valor-chave
- Subdocumento operações
-
O código-fonte completo desta série está disponível no GitHub.
O que vem a seguir?
Inscreva-se para um teste gratuito do Capella. O Couchbase Capella DBaaS é a maneira mais fácil de começar a usar o Couchbase, e não é necessário cartão de crédito.
Confira o Couchbase Playground para .NET exemplos que você pode executar diretamente no navegador.
Participe do Discórdia do Couchbase para fazer perguntas e trocar comentários com os engenheiros do Couchbase e com outros membros da comunidade do Couchbase.