Esta serie de ASP.NET Core CRUD está llegando a su fin. Hemos cubierto configuración (parte 1), lectura con SQL++ (parte 2), lectura con clave-valor (parte 3)y crear/actualizar (parte 4). En este último post, veremos la D en CRUD: borrar.
Borrado con SQL++ o clave-valor
Espero que estés notando un patrón. Al igual que con la lectura, creación y actualización, tienes múltiples caminos para borrar. Puedes usar un SQL++ BORRAR declaración:
1 2 |
BORRAR DESDE demo.Por defecto.lista de deseos w DONDE META(w).id = "1c3de2e7-70ea-4ee2-803b-425bbf6251cb" |
También puede utilizar una operación de eliminación de clave-valor (también conocida como "Eliminar“):
1 |
await colección.RemoveAsync("1c3de2e7-70ea-4ee2-803b-425bbf6251cb"); |
Y como antes, aquí tienes unas pautas muy parecidas para ayudarte a decidir cuál utilizar:
Caso práctico | ¿Clave-valor? | ¿Por qué sí o por qué no? |
Eliminar un usuario con clave "73892" | Sí | Acceso directo |
Eliminar un grupo de usuarios con las claves "73892", "47212" y "90491". | Sí | Esto puede requerir múltiples operaciones clave-valor, pero aún así puede ser más rápido que utilizar un SQL SUPRIMIR ... DONDE ... EN consulta. |
Borrar todos los usuarios de "Ohio" | No | El estado del usuario es probablemente un atributo "secundario", no una clave (varios usuarios pueden ser de Ohio). Este es un buen caso de uso para un SQL++. BORRAR |
Un punto final de eliminación para ASP.NET Core
Con esto en mente, crea un punto final de borrado como este:
1 2 3 4 5 6 7 8 9 10 11 |
[HttpDelete] [Ruta("api/delete")] público async Tarea<IActionResult> Borrar(Guía id) { var cubo = await _bucketProvider.GetBucketAsync("demo"); var colección = await cubo.ColecciónAsync("lista de deseos"); await colección.RemoveAsync(id.ToString()); devolver Ok(nuevo { éxito = verdadero }); } |
Pruebe este endpoint con OpenAPI / Swagger, y se comportará como cabría esperar.
¿Debería borrarlo?
En muchos casos de uso, es posible que no desee en realidad borrar datos. Puede que quiera hacer algo llamado borrado "suave". Esto implica mover o marcar los datos de tal forma que sigan existiendo en la base de datos, pero ya no se muestren al usuario final. Esto tiene la ventaja de que se pueden descubrir, recuperar y notificar.
También es una gran oportunidad para mostrar la flexibilidad de una base de datos JSON NoSQL.
Borrado suave
Introduzcamos un campo "eliminado" en los elementos de la lista de deseos. Este campo contendrá la fecha/hora en que se eliminó el artículo. Si este campo existe, el resto del endpoint debería considerar que este artículo ha sido eliminado. Sin embargo, si lo necesitamos, aún podemos consultarlo, informar sobre él y recuperarlo.
En una base de datos relacional, esto requeriría probablemente un ALTERAR. Dependiendo del tamaño de tus datos, podría requerir algún tiempo de inactividad, o posiblemente un montón de valores NULL. En una base de datos JSON, no necesitamos decirle nada a la base de datos sobre un nuevo campo.
Utilicemos el API de subdocumentos para añadir un "suprimido"al documento. Subdocumento significa que sólo operaremos sobre un porción del JSON, y dejar el resto solo.
1 2 3 4 5 6 7 8 9 10 11 12 |
[HttpDelete] [Ruta("api/softDelete")] público async Tarea<IActionResult> SoftDelete(Guía id) { var cubo = await _bucketProvider.GetBucketAsync("demo"); var colección = await cubo.ColecciónAsync("lista de deseos"); await colección.MutateInAsync(id.ToString(), opciones => opciones.Upsert("borrado", FechaHora.Ahora)); devolver Ok(nuevo { éxito = verdadero }); } |
(Asegúrese de que utilizando Couchbase.KeyValue; está en la parte superior de su GiftsController archivo).
Este código envía una orden a Couchbase: para el documento con tal y tal ID, upsert un campo llamado "suprimido"y dale como valor la fecha/hora actual.
Fíjate en que con el subdocumento no tenemos que cargar primero el documento existente y no tenemos que enviar todo el documento modificado de vuelta a través del cable.
Datos borrados
El resultado final será un documento con este aspecto:
1 2 3 4 |
{ "nombre": "Marco de fotos digital", "borrado": "2022-04-21T11:05:26.1766248-04:00" } |
Los demás documentos de mi lista de deseos sí no tener un suprimido campo. Siguen pareciendo:
1 2 3 |
{ "nombre": "Camiseta Skyline Chili 2XL" } |
y
1 2 3 |
{ "nombre": "Joey Votto jersey" } |
Tenga en cuenta que no tienen "suprimido": null campo; no tienen “suprimido“ campo en absoluto.
Borrado suave SELECT
Los datos son marcado como eliminado, pero sigue en la base de datos. Tenemos que modificar el GetAll punto final (consulte la parte 2 para obtener más información GetAll) para tenerlo en cuenta:
1 2 3 |
SELECCIONE META(w).id, w.* DESDE demo.Por defecto.lista de deseos w DONDE w.suprimido IS FALTA |
Aquí he introducido algo más de sintaxis SQL++: FALTA. Se trata de un concepto que no existe en las bases de datos relacionales. En relacional, cualquier columna especificada en la consulta debe estar definida y debe tener un valor (incluso si es nulo). Con una base de datos de documentos JSON NoSQL, no existe tal restricción.
Mejorar el índice
Un último punto a tratar es la indexación. En parte 2hemos creado un índice primario para empezar. Sin embargo, ese índice rara vez será el más eficiente. Creación y ajuste de índices es un tema profundo, como lo es en el mundo de las bases de datos relacionales.
Afortunadamente, Couchbase Capella tiene incorporado un Aconsejar herramienta que puede recomendar mejores índices. Haga clic en Aconsejar en el Query Workbench (o puede utilizar CONSEJO sintaxis).
En este caso, da la siguiente recomendación:
1 2 3 4 5 6 7 8 9 10 11 |
"índices_recomendados": { "índices": [ { "declaración_í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", "contexto_consulta": "default:demo._default", "recomendando_regla": "Las claves de índice siguen el orden de los tipos de predicado: 2. igualdad/nulo/falta". } ] } |
En el caso de nuestra pequeñísima cantidad de datos de listas de deseos, probablemente no merezca la pena crear este índice. Sin embargo, si estuviéramos gestionando las listas de deseos de todo un sitio de comercio electrónico (por ejemplo), este índice sería un buen punto de partida.
El fin del CRUD
Hemos llegado al final de la creación de una aplicación ASP.NET Core CRUD muy sencilla con Couchbase. La superficie final de la API tiene este aspecto:
Aquí tienes un desglose de los conceptos de esta serie, con enlaces a documentación para profundizar:
-
- Configuración de Capella
- Configuración de la inyección de dependencias .NET
- SQL (a veces se sigue llamando "N1QL")
-
-
- Operaciones CRUD clave-valor
- Subdocumento operaciones
-
El código fuente completo de esta serie está disponible en GitHub.
¿Y ahora qué?
Prueba gratuita de Capella. Couchbase Capella DBaaS es la forma más fácil de empezar con Couchbase, y no se requiere tarjeta de crédito.
Echa un vistazo a la Couchbase Playground para .NET que puede ejecutar directamente en el navegador.
Únete al Couchbase Discord para hacer preguntas e intercambiar comentarios con los ingenieros de Couchbase y con otros miembros de la comunidad Couchbase.