Transcripciones
1. Introducción: Bienvenido a este nuevo curso Entity Framework
Core, un Tour completo. Mi nombre es Trevor Williams, y soy
ingeniero de software y conferencista con más de diez años de experiencia
en el desarrollo de aplicaciones, además de enseñar a la
gente cómo hacerlo En este curso,
vas a aprender sobre Entity Framework Core,
y este es el framework de acceso a
datos insignia de Microsoft o ORM para punto t Ahora
en este curso, vamos a pasar
por algunas cosas que
te colocarán por encima y más allá de
tus compañeros y tus colegas en términos de cómo interactúas con
tus bases
de datos mientras
construyes aplicaciones.NET. Vamos a explorar el framework de
entidades y cómo te
ayuda a construir
aplicaciones más rápido en.net, así
como cómo te
ayuda a administrar creación y los cambios de
bases usando simplemente la sintaxis C sharp Así es. Utilizando
Entity Framework Core. No necesariamente
tienes que ir a SQL
o ir al estudio de
administración para manipular tu base de datos,
y
al final de este curso, vas a tener una
buena comprensión de
cómo se administra todo esto a
través de migraciones,
el contexto de la base de datos
y los modelos de base Vas a entender
cómo escribir consultas de enlace para interactuar con tus
objetos y tablas de base de datos, así
como explorar muchas
otras características avanzadas núcleo
de Entity Framework. Ahora, al final de este curso, se supone que debes
sentirte cómodo con framework de
entidades y
cómo te permite
escribir consultas de enlaces, e interactuar con tus datos. Un poco de historia sobre el marco de
la entidad. Ha estado en desarrollo
desde 2008 en DottFramework, pero ha evolucionado y evolucionado y
evolucionado y ahora mismo estamos en D
cinco o Dt COR cinco Y así la biblioteca, que actualmente se encuentra en uso en estado estable es EF Core five, que es lo que
vamos a estar explorando. No obstante, pronto
habrá EFC seis, y la mayor parte de lo que
vamos a aprender aquí serán conocimientos
transferibles. Ahora, un poco más
sobre lo que es EF COR. Es un mapper
relacional de objetos. Antes usé el acrónimo ORM. Eso es lo que representa. Asignador relacional de objetos. Por lo que es una biblioteca de
código abierto con API que facilitan la interacción
con la base de datos. Si bien usaremos SQL
Server en este curso, muchas capacidades de FCR se
pueden extender a otras bases de datos como post
resca y cuaide y my ca. Así que hay muchos
beneficios por venir de aprender C porque Le ayuda a reducir la
repetición de código, y le permite
centrarse en otras cosas en
su aplicación mientras mantiene el código basado agradable y
consistente en todo momento. También está
listo para la empresa. Así es. Si estás construyendo una
aplicación grande y te preocupa tener
demasiadas consultas y
tener código mesic, FCR es perfecto para ti porque
es agradable, es compacto Permite mantener
la sintaxis en C nítida, y es lo suficientemente estable como para
trabajar en condiciones extremas. Sé que estás viendo
este curso y te preguntas, ¿este curso es realmente para mí? Bueno, si quieres aprender sobre FCR, estás en el lugar correcto Si conoces algo de C sharp y tienes algún conocimiento de
base de datos, estás en el lugar correcto. Si quieres aprender formas
modernas de interactuar con tu base de datos
usando tecnología, entonces definitivamente estás
en el lugar correcto. Al finalizar este
curso,
no tendrás debilidades y no
hay amenazas. Sólo se puede conseguir
mejor y mejor. Entonces, ¿a qué esperas? Estoy feliz de
tenerte en este curso, y te veré en
la próxima conferencia.
2. Entorno de la configuración del desarrollo: Oigan, chicos, bienvenidos de nuevo.
Entonces en esta lección, solo
voy a
guiarte a través de lo que necesitas para configurar tu entorno
para este curso. Entonces ya estoy aquí en la web de
Visual Studio, puedes llegar diciendo
sutudo.microsoft.com Y lo que vamos
a usar es la edición
comunitaria IDE de Visual Studio. No, este es el IDE
insignia
que nos da Microsoft para el desarrollo
de.NET Por lo que es perfecto
para este curso. Sin embargo, si no puedes
usar esa edición comunitaria, en una máquina con Windows
y estás usando un MAC, entonces ellos tienen la versión MAC. Si no estás usando un MAC, entonces puedes usar el código de
Visual Studio, que también es de código abierto
completamente gratuito y disponible en cada uno
de los sistemas operativos. Ahora bien, las cosas que voy a
hacer en este curso
diferirán si estás usando código de
Visual Studio, pero haré todo lo posible para tomar
notas en el camino para intentar asegurarme de que
eres capaz de llevar a
cabo las operaciones. Ahora, después de descargar
Visual Studio, se
te dará bien, al
menos descargando
el instalador, después de lanzar este instalador, se
te dará una
pantalla similar a esta. Ahora, ya
lo tengo en mi máquina, y lo que están viendo son
las diferentes cargas de trabajo que ya
tengo instaladas No necesitas tantos
para este curso en particular. Si ya tienes los
que estoy a punto de mostrarte, entonces puedes seguir adelante
y saltarte este paso. Pero si estás aquí, y necesitas
saber qué conseguir. Necesitas esta carga de trabajo de desarrollo
multiplataforma .net, lo que nos da lo
real que sabes, las bibliotecas básicas para
el
desarrollo core .net Y vamos a estar haciendo un
poco de actividad web. Por lo que sería una buena
idea simplemente obtener la red AP y la carga de trabajo de
desarrollo web también. Entonces, como mínimo,
necesitas a esos dos. Cuanto más hagas clic, claro, más
se instalará,
así que no tienes que
hacer clic en tantos como veas que me hayas marcado aquí Así AP net y desarrollo web así
como as.net desarrollo
multiplataforma. Entonces puedes seguir adelante
e instalarlos ahora, necesitas completar este paso, sobre todo si no estás usando el Visual Studio y
una máquina Windows, porque si vas a
estar usando código de Visual Studio, entonces necesitas instalar
el SDK en segundo plano. Eso viene con
Visual Studio, ¿verdad? Pero entonces si no estás usando
Visual Studio una vez más, puedes seguir adelante y
descargar ese SDK, así que solo puedes
llegar aquí yendo a Microsoft co. Y
desde esa landing page, podrás navegar por la página
de descargas.t5 donde vas a
conseguir ese SDK También puedes seguir adelante y obtener los tiempos de ejecución porque los
necesitamos para el hosting, pero al menos
necesitas ese SDK. Bien. Ahora, después de que todo haya sido instalado y configurado, solo
quiere asegurarse de
que todo esté instalado. Entonces puedes ir a
tu símbolo del sistema, cualquiera que sea el sistema operativo que esté encendido, y luego simplemente puedes
escribir .net H. ¿De Entonces, cuando hagas eso,
sacarás a colación si estás viendo un printo en la pantalla
luciendo algo así, entonces estás en el camino correcto Entonces te dirá la versión del
SDK que tienes, y solo te mostrará todos
los diferentes comandos
que puedes usar. Así que en realidad puedes usar
estos comandos al crear una nueva aplicación.net
core, y especialmente una vez más, si estás usando código de
Visual Studio, entonces definitivamente
vas a estar usando comandos.net un poco Todo bien. Entonces eso es realmente todo para configurar
el entorno. Este es un video de cinco minutos, pero
probablemente tomará unas horas o unos minutos más en lugar esto si estás
configurando desde cero, pero no tardará demasiado. Así que en cuanto
termines y
puedas verificar que tienes
todo instalado, entonces podrás pasar a
la siguiente lección. Bien.
3. Configuración de la solución: Oigan, chicos, bienvenidos de
nuevo en esta lección, vamos a empezar a configurar nuestra solución para el
proyecto o para este curso. Y lo que vamos a hacer es comenzar con una solución en blanco. Entonces voy a seguir adelante y
hacer clic en Crear nuevo proyecto, y solo voy a buscar la plantilla de solución en blanco. Y ese es el que
vamos a seleccionar. Así que adelante, golpea siguiente. Y voy a
llamar a la solución llamada entidad framework net five, derecho, indicativo del
curso que estamos haciendo. Y tener mi ubicación establecida Voy a seguir
adelante y hacer clic en crear. Y así,
tenemos Visual Studio con nuestro archivo de solución en blanco. Lo que vamos
a hacer es comenzar agregando un nuevo
proyecto a la solución. Entonces voy a agregar un nuevo proyecto, y luego voy a estar agregando una aplicación de consola porque
vamos a estar usando una aplicación de consola para pasar por los fundamentos
del núcleo de framework de
entidad ¿Verdad? Antes de entrar en toda la emoción de la web
y esto y aquello, quiero que entendamos
lo que puede hacer FCR, porque si
lo entendemos desde una app de consola, entonces las posibilidades
son ilimitadas cuando tenemos que construir aplicaciones más
complicadas Así que vamos a seguir adelante, haga clic en
Aplicación de consola, presione Siguiente, y vamos a
llamar a esto one entity framework net five console app. Así que adelante, golpea siguiente otra vez. Estamos apuntando a t cinco
como nuestro marco objetivo, y luego seguir adelante y crear. Bien. Ahora mismo que se crea nuestra aplicación de
consola. Vamos a crear
dos proyectos más, y estos realmente van
a ser bibliotecas de clases. Ahora bien, en el desarrollo empresarial, uno de los
principios fundamentales es la separación de preocupaciones, decir, tenemos la aplicación, es
decir, tenemos la aplicación,
que probablemente va a estar haciendo jalando los hilos,
hablando con el usuario. Pero entonces necesitamos otros proyectos donde vamos a estar almacenando objetos relacionados con
bases de datos y configuraciones relacionadas con
bases de datos están separadas. Entonces por eso estamos agregando dos proyectos más en
forma de biblioteca de clases. Entonces tengo biblioteca de clase
a la izquierda aquí. Siempre puedes desplazarte, pero puedes hacer búsqueda
si es necesario y
recuerda siempre que estamos tratando
con C sharp. ¿Todo bien? Entonces, para la biblioteca de clases, vamos a llamar a
esta primera entidad framework
net five dot data. Y entonces sigue siendo el
marco objetivo sigue siendo t cinco, y luego golpeamos Crear. Y por último, pero de ninguna manera menos importante, vamos a seguir adelante y
agregar una biblioteca de clases más, y esta va
a ser dominio punto. Entonces la misma
convención de nomenclatura que tenemos entidad framework net
five dot domain, ¿verdad? Y sigue siendo un marco
objetivo de.t5, y luego seguimos adelante y agregamos Entonces eso es realmente todo
para la configuración de nuestra solución. Entonces, una vez más,
vamos a estar operando
con tres proyectos, al
menos ahora mismo, tres proyectos
diferentes. Este, el
listado de aplicaciones de consola de la misma como la interfaz de usuario, se
puede ver aquí como un tipo de
salida de ejecutable. Entonces sabe que debe ejecutar o debe
hacer algo. Eso es así que
se
configuran los archivos de configuración central o de proyecto porque
si miras este diferente de
la biblioteca de clases, verás que este solo
tiene el framework de destino. Este sabe que es framework
objetivo, y el hecho de que
es un ejecutable. Esa es la única diferencia material
entre ellos dos, ¿verdad? Entonces este representará dónde vamos a estar
escribiendo nuestro código práctico, pero luego estaremos configurando nuestro dominio y
objetos de datos dentro de aquí. Bueno, el dominio tendrá nuestros modelos de
datos para clases, y luego los datos tendrán nuestras configuraciones de datos
y archivos. Entonces cuando lleguemos
empezaremos un poco de diversión y empezaremos a modelar
algunas de las tablas que estaremos usando
para este curso.
4. Crea los modelos de datos con EF Core: Ustedes son bienvenidos de nuevo.
Entonces en esta lección, vamos a empezar a modelar
nuestras tablas de base de datos. Ahora bien, lo que tengo en pantalla es un diagrama de base de datos o diagrama de relación de
entidad ERD Tiene algunos nombres, y hay algunas
representaciones del mismo. Pero el concepto fundamental es que se trata de un diagrama que muestra las diferentes entidades
o tablas dentro de una base de datos y cuál es la columna de clave
primaria, cuáles son los otros campos, y luego se representa que
existe lo que llamamos una relación de clave externa
entre dos tablas. Aquí, está demostrando que
tenemos equipos y tenemos ligas. Esas son dos mesas. La liga tiene un ID, que vamos a hacer un
entero auto incrementante y tiene un nombre Y luego un equipo también tiene una identificación, también como nombre, pero luego
tiene una identificación de liga. Este ID de liga es lo que
llamamos una clave foránea
de la liga. Un equipo pertenece a una liga. Esa es la relación. Si estás familiarizado
con la base de datos, entonces ya sabes
lo que está pasando. Si no estás tan familiarizado,
entonces eso no es problema. Espero que entiendas al
menos el concepto detrás de este diagrama. Todo bien. Sin embargo, lo que queremos hacer es configurar mesas como
esta dentro de EFC Queremos utilizar FCO para modelar una base
de datos que
generará estas tablas Entonces tienes diferentes
convenciones a la
hora de desarrollar
encima de una base de datos. Entonces podemos hacerlo primero la base de datos, es
decir, alguien entró
diseñó la base de datos y todo y luego comenzamos a construir la
aplicación después, o primero tienes código, lo
que a pesar de
que implica que el código viene primero, lo que realmente significa es
que vamos a escribir el código que luego se
convierte en la base de datos. De esa manera, si necesitamos cambiar
algo en el futuro, en realidad solo
cambiamos el código, y luego podemos dejar que eso haga cambios incrementales
para establecer la base de datos. Y EFC soporta cualquiera de ellos.
Esa es la belleza de la misma. Entonces, para la mayor parte
de este curso, vamos a estar
viendo
primero el código y cómo podemos hacer cambios
marginales o cambios
incrementales medida que avanzamos
modificando el código. Pero veremos cómo aplicar ingeniería inversa
a base de datos
existente en
un conjunto de archivos EFC, ¿verdad Así que basta de
platicar, entremos en eso. Entonces mis modelos de datos o modelos de
dominio
van a terminar yendo en el
proyecto de dominio, ¿verdad? Entonces me voy a deshacer de esta clase predeterminada
que obtuvimos con ella, y voy a seguir adelante
y agregar una nueva clase, y voy a llamar a
esta liga de clases. Ahora bien, en términos generales,
siempre aconsejo a mis alumnos, siempre que estén
creando una base de datos, siempre que estén
creando una base de datos,
intenten comenzar
con
las que tengan menos dependencias
y luego continúe porque no quiere
construir una tabla que tenga dos o tres
claves externas
relacionadas con otras tablas y esas
tablas aún no existen Ya que en esta situación,
la Liga es una tabla independiente, es
decir, la liga está ahí. Una liga va a estar ahí al
menos ahora mismo
sin ningún equipo, pero el equipo
depende de la liga. Quiero que la liga exista primero. Crea esa clase,
voy a hacerla pública para que otros
proyectos puedan acceder a ella. Y luego dentro de esto, voy a tener las dos
propiedades, ID y nombre. Así que vamos a decir public
int ID, public string name. Ves aquí,
sobre todo si estás familiarizado con los tipos de
datos en SQL, verás que aquí no estamos viendo Var char. Estamos
diciendo cadena. FCR podrá traducir el C nítido nativo
de qué tipos de datos En los tipos de datos
SQL equivalentes. Ya lo veremos más adelante. Ese es uno de los beneficios. Podemos usar nuestro C sharp nativo dentro de nuestra aplicación FCO, y la traducción a
la base de datos nos
pasará de forma anónima Otra
cosa importante a señalar son las convenciones de nomenclatura y el apoyo que obtienes de FCO cuando sigues
ciertas En términos generales, una columna de ID se va a llamar ID. A veces podrías calificar y decir ID de liga o
el ID del nombre de la tabla. Ahora, COR identificará
cualquiera de estas convenciones, y automáticamente
inferirá que esta
pretende ser su clave principal y columna de
identidad QL de
incremento automático columna de
identidad QL de
incremento automático Entonces automáticamente verá esa convención de nomenclatura y le dirá a SQL que esta es
la columna de clave principal Entonces, si te quitas el camino de esa convención
general de nomenclatura, entonces vas a
tener que hacer
configuraciones adicionales para que eso
funcione Entonces para mí, es más fácil simplemente
trabajar con FCR que forzar el cable F
en otro pase No es
lo más difícil de hacer, pero ¿por qué darte más
trabajo cuando puede ser así de fácil tan solo decir ID,
sabrás que esta es la clave principal y encajar
todo lo demás para mí. Ahora, voy a crear
la siguiente tabla o la siguiente clase representar la
siguiente tabla, que es equipo. Solo estoy agregando eso
al proyecto de dominio. Equipo es el nombre, y
luego equipo una vez más, público también
tendrá identificación y nombre. Como vimos, pero luego
tiene una tercera columna, que es el ID de liga. Eso representa una clave foránea. Ahora bien, lo que vamos a hacer
cuando tengamos una clave externa, tenemos que agregar dos propiedades. Uno, siendo el nombre de la tabla o el nombre de la
tabla a la que esta es una clave externa e ID. Una vez más, convención de nomenclatura. Segundo sería una propiedad de
navegación y la mayoría de las veces
los verás haciendo esto virtual. Vamos a agregar eso. Liga de liga
virtual pública siendo tipo de
datos de la clase que
acabamos de crear con el mismo nombre. Eso está bien. Pero
la combinación de estos dejará F para inferir que esta coincidencia con el nombre de la
tabla y la palabra ID significa que esta es una clave
externa para esa tabla Todo bien. Entonces, si
has tenido que configurar una clave foránea en SQL Server, sabes que
tienes que entrar y tienes que elegir las columnas, y tienes que hacer
esto, y tienes que
hacer eso. Y
hay algunos pasos. Esto es todo lo que se necesita. Siga
la convención de nomenclatura y tenga esa propiedad de
navegación Y FCO solo dirá,
Bien, sé que esta
es una clave foránea, y sé que automáticamente
puedo
incluir o
presentar automáticamente incluir o
presentar automáticamente los detalles relacionados a este registro a través de
esta propiedad Más adelante, lo veremos a la una para mostrar demasiada información. Pero solo estoy tratando de
mostrarte que desde el principio, una vez que sigas estas convenciones
fundamentales de nomenclatura, FCR va a hacer mucho
del trabajo por Bien. Entonces eso es
realmente todo por ahora. Hemos creado las clases que se supone representan las tablas en
la base de datos. Por supuesto, los nombres de columna que
coinciden con los tipos de datos son conceptualmente los
mismos que
esperaríamos que fueran en la base Y más adelante cuando regresemos, vamos a ver cómo
configuramos el contexto DB, el proveedor y
la conexión
real a
la base de datos porque nada
de eso existe en este momento. No hay base de datos. Sólo lo estamos
modelando y diciendo:
Bueno, estos representan
lo que quiero almacenar. Entonces, cuando volvamos,
vamos a ver cómo configuramos realmente el
enlace a la base de datos. Bien.
5. Especificar el proveedor de datos y la serie de conexión: Nuestros chicos volvieron y el objetivo de esta
lección es configurar nuestra clase de datos para
que sepa que necesita conectarse a
nuestra base de datos. Todo bien. Entonces, nuestra clase de datos, vamos a tener que agregar
algunas bibliotecas a esto para que realmente interactúe
con ese framework de red. Lo siento, con marco de entidad. Porque ahora mismo,
nadie sabe nada. Sólo estamos
hablando de framework de entidades. Se llama entity framework, pero no sabe nada
sobre entity framework. Así que permítanme comenzar
eliminando esta clase predeterminada, y voy a saltar a los nuevos paquetes de puerta
y vamos a ir a Bros y vamos
a estar buscando entidad Framework
core SQL server. Entonces antes de seguir adelante e instalar eso en el salto,
déjame explicarte. Tienes Microsoft
Entity Framework Core. Esta es la
biblioteca base para todos. Creo que cada variación
tiene una dependencia de ésta. Si lo miras, es
un moderno
mapper basado en objetos para.admite
consultas de enlaces, seguimiento de cambios y funciona con una
serie de bases de datos, servidor
CQL, Azure, postres CQight Lo que te das cuenta
es que a partir de UGT, en realidad
puedes obtener
diferentes bibliotecas para soportar las
diferentes bases En nuestro caso, estamos usando
Microsoft k server. Pero si tuviera que buscar núcleo de framework de
entidad y simplemente mirar a través de las
diferentes variaciones que vemos nuestro servidor k, vemos en la memoria, vemos CQight Ves Postgres,
vas a ver MCL. No voy a
pasar por todas ellas, pero el punto es que
sea cual sea la base de datos que
sea la que tengas bajo el capó, es más que
probable que
haya una biblioteca para apoyarla y la puedas
obtener de New gt. Todo bien. Como dije, hoy solo estamos trabajando
con SQL Server, así que sigamos adelante
e instalemos ese, así que solo voy
a descargarlo. Y al hacerlo, te
va a mostrar todas
las demás dependencias que tiene, ¿verdad? Pero eso está bien. Podemos simplemente seguir adelante
y hacer clic en Bien, aceptar cualquier
acuerdo de licencia y dejar que
lo instale en nuestro proyecto. Entonces ahora que está
instalado en nuestro proyecto. Si miro hacia atrás en el archivo CSP, simplemente haciendo clic en
el archivo del proyecto para los datos del proyecto de datos Verás aquí que ahora tenemos instalada
esa
referencia de paquete. Alternativamente, también
podrías haber seguido adelante y poner esa
línea similar a esta. Podría decir referencia de
paquete de nodo, incluir el nombre de
la biblioteca, la versión que
te interese, y luego solo para
construir y
automáticamente irá y obtendrá
las dependencias por ti Entonces podría haber hecho eso también, pero procedamos usando NewG Así puedo cerrar todo eso. Y lo siguiente en la agenda sería crear lo que
llamamos el contexto DB. Entonces quiero crear
otra clase
y luego voy a llamar a esta clase contexto de liga de fútbol liga fútbol o contexto DB de liga de
fútbol. Tendemos a poner eso en, contexto
DB solo significa que es el contexto o la conexión. Digamos que el contexto
es igual a la conexión. Contexto DB significa archivo de
conexión DB, por así decirlo. Y entonces esto es solo
dejarte saber qué base de datos es. No es una
convención de nomenclatura per se. Así es como lo estoy
haciendo. Sólo te estoy
explicando por qué lo estoy
nombrando así Así que voy a hacer este contexto
público de base de datos de clase pública, y luego cada contexto DB
va a heredar del contexto DB predeterminado
proveniente del núcleo EF Entonces tienes diferentes contextos de
base de datos, tienes contexto de base de datos, tienes contexto de base de datos de identidad si quieres autenticación de usuario. Pero por ahora, solo nos cegaremos
al contexto básico de base de datos, control y punto y
luego eso me hará
saber que necesito una
declaración de uso para framework de entidad. Núcleo. Ahora eso está satisfecho. Puedo contarlo de las mesas. Recuerda, esto va a representar la conexión
a la base de datos. Entonces, lo que sea que esté en la base de datos necesita
ser representado aquí. Tenemos los modelos que representan las tablas
en la base de datos. Ahora tenemos el enlace
a la base de datos, necesitamos que este enlace
sepa sobre las tablas. Entonces quiero decir conjunto de DB público. Y este conjunto DB set
solo significa que el conjunto de filas o registros son realmente
una tabla en la base de datos. Estás modelado de
equipo Todo bien. Y tu nombre son equipos. Así que puedes
leerlo así solo di
entender exactamente lo que estás
escribiendo a medida que avanzas. No, necesito tener una dependencia. Tengo que añadir aquí una referencia
al proyecto de dominio. Y así solo voy a que
pudieras hacer clic en eso, pero he tenido problemas
con eso antes, así que solo voy
a seguir adelante y
hacerlo manualmente haga clic en dependencias, agregue referencia de proyecto, y
luego agregue el proyecto de dominio, haga clic, y luego simplemente podemos seguir
adelante y
usar nuestras declaraciones de uso Entonces solo voy a
duplicar esa línea y hacer lo mismo por una liga que
la DB fijó para liga, la estamos llamando ligas
en la base de datos. Tengo un conjunto de bases de datos
para objetos de equipo, estamos llamando a eso equipos. Esto, una vez más,
generará o interactuará con
una mesa llamada equipos, y todo lo que esté
en la tabla de equipos será serializado o convertido a la
clase de equipo nativo que hayamos definido Lo siguiente que quiero hacer es en realidad hacerle saber
sobre una base de datos, y tenemos que hacer lo que
llamamos una
cadena de conexión para eso. Entonces, las cadenas de conexión generalmente, como en una aplicación web, se
pasarían, así que
tienes la cadena de conexión
en la aplicación web y se pasa a través ajustes de
configuración
al contexto. No tenemos ese
lujo en este momento, así que solo lo haremos manualmente, así que voy a escribir override. Y entonces la cosa es
que el contexto DB, que es nuestra clase EFC
viene con una serie de funciones que realmente podemos sobrescribir y hacer lo
nuestro propio Pero el que me
interesa es configurar. Esto significa que cada vez que estás
configurando el contexto DB, ¿
qué quieres que haga? Voy a anularlo. No necesito anular nada en la base ni
interactuar con la base, pero voy a
decirle que el servidor UCL generador de
opciones Ves que es cortesía
de nuestro servidor punto, biblioteca
FCR, ¿verdad Entonces UEQL servidor. Y vamos a poner en nuestra
cadena de conexión aquí mismo. Debido a que esta es una app demo en las primeras etapas, estamos
haciendo todo esto. Pero claro, te estoy
guiando a través de ello para
que entiendas por qué lo estamos
haciendo de esta manera. Entonces una cadena de conexión
comprende algunas partes. Vamos a decir, la
fuente de datos es igual a, y luego
especificaríamos el servidor. Entonces estaré usando la base de datos local, que es un servidor local
integrado en Visual Studio, y puedes acceder a
bases de datos locales de base de datos a través del explorador de objetos
del servidor SQL, que puedes ir a ver, y ahí está. Todo bien. Local D B, barra diagonal, barra diagonal, y luego vamos
a decir SQL local D B. Obtener Solo tómate un tiempo y consíguelo
tal como lo ves aquí, incluso con los paréntesis
y todo, la doble barra diagonal
y todo A continuación, tenemos
el catálogo inicial y este es básicamente el
nombre de la base de datos. ¿Cómo estamos llamando a
la base de datos? Voy a llamarlo
Liga de Fútbol subrayado FCR. Esa es nuestra
cadena de conexión. Todo bien. Y con eso,
en realidad hemos terminado de configurar el proveedor de datos y configurar el enlace
a la base de datos. Ahora, claro, esta base de datos aún
no existe, ¿verdad? Así que he establecido un enlace a algo que no está
ahí prácticamente. Y he dicho que estas tablas
necesitan existir en base de datos de conjuntos, que, como acabamos de
decir, no existe. Así que solo voy a buscar en
el explorador de servidores SGO muy rápido solo para mostrarte que realmente
no existe ahí dentro Tengo algunas bases de datos de prueba, y como pueden ver,
no está ahí. Entonces, cuando volvamos, lo que vamos a
estar haciendo usando FCO para generar esta base de datos para
que podamos empezar a
interactuar con ella
6. Migraciones y bases de datos: Oigan, chicos, bienvenidos de nuevo.
Entonces en la última lección habíamos configurado nuestro contexto DV,
que, como dije, es nuestra
conexión con la base de datos. En esta lección, vamos a
empezar a mirar las migraciones, que son nuestras instrucciones
a la base Nuestra primera migración será
crear la base de datos porque
una migración siempre dirá, ¿qué existió, qué existe ahora? ¿Qué es diferente? Déjenme dar instrucciones para
hacer esos cambios. En este punto, no hay nada. Entonces lo que hay ahora no es nada, y entonces las instrucciones
generarán lo que debería estar ahí. ¿Verdad? Entonces, para poder
hacer nuestras migraciones, necesitamos otra herramienta de
nuestros nuevos paquetes gate, y esa biblioteca es
literalmente herramientas, ¿verdad Necesitamos FC dos. Ir
a New Gate, voy a seguir adelante y golpear
herramientas y descargar
esa y eso viene
automáticamente con diseño
y algunas otras bibliotecas, pero solo voy a
seguir adelante y dejar que eso se instale. Después de instalar eso, voy a tener que establecer una
referencia de proyecto entre la consola y nuestro proyecto de datos porque cuando ejecutamos un comando
para actualizar la base de datos, tenemos que hacer que se ejecute contra el proyecto de inicio
o el proyecto principal, y el proyecto principal necesita
conocer los otros
proyectos con, ya
sabes, la conexión y
el contexto DB y así sucesivamente. Así que solo voy
a seguir adelante y agregar una referencia de proyecto
para consolar para ambos porque necesitaremos poder
acceder a los objetos de dominio. También necesitamos
poder acceder al dominio
el
contexto DB, ¿verdad? Entonces solo voy a seguir
adelante y agregar eso Y luego saber que
todo eso está hecho, podemos ejecutar una migración. Para ejecutar migraciones
usando Visual Studio, queremos ir a la consola
del administrador de paquetes Entonces puedes ir a herramientas, obtienes administrador de paquetes y
ves la consola del administrador de paquetes. Tengo el mío disponible para mí ya
aquí abajo en este panel, y por supuesto, puedes
mover los paneles todos hacia arriba. Déjame rehacer esta. Ahora, antes de comenzar
las migraciones, solo
quiero que echemos
un vistazo al alcance de las opciones disponibles para nosotros. En esta consola del gestor de paquetes, puedo decir ponerse cadera y ayudar y luego escribir
en entity framework, y luego darle unos segundos,
y luego
generará un bonito documento que y luego
generará un bonito documento nos
muestre todo lo que es
posible a través del framework de la
entidad. Comienza con un unicornio y nos
habla de la biblioteca, nos
da todos los
lets de comando y para qué se utilizan. La misma lista que
acabo de señalar en GT, está disponible aquí
con documentación. Entonces como dije, vamos a
estar agregando una migración, y luego tendremos que actualizar la base de datos después de
cada migración. Mencioné anteriormente
que tienes código primero versus
base de datos primero. Entonces, si estás haciendo código primero,
bueno, esa es la base de datos de actualización de agregar
migración. Si estás haciendo base de datos primero, entonces
querrías sca contexto FO DB,
que básicamente dice, estoy
mirando la base de datos y
generando los modelos de clase basados en lo que veo
en la base Entonces ves que tienen
bastantes opciones disponibles. Puede escribir el contexto DV,
Scripto las migraciones. Si aún estás anticuado
para generar la migración, quieres un script SQL. Puedes hacer todo eso
usando estas herramientas. Entonces, sigamos adelante. Yo solo voy a
despejar este CLS, limpiar esa consola, y luego voy a
saber agregar una migración Entonces el
proyecto predeterminado, una vez más, necesita ser el
proyecto ejecutor en la solución. Y voy a
decir agregar migración. Y luego le voy
a dar nombre. Entonces el nombre, típicamente, quieres usar un nombre
lo suficientemente
sensible como para ti o alguien más. Bueno, comencemos
con alguien más. Alguien más puede
venir y decir: Bien, eso es lo que esa fue una
idea general de esa migración. También quieres
usar un nombre sensato porque después de irte de
vacaciones y volver, quieres mirar hacia atrás
en esta migración y entender por qué se
hizo y para qué fue. Así que no pongas el nombre de la migración X o simplemente algo tonto,
dale algún sentido. Entonces como si no hubiera nada aquí. No tengo migraciones,
ni base de datos. Sin embargo. Quiero llamar a esta
migración inicial. También me gusta camello
caso mis nombres. Cuando usas espacios, entonces tienes que tomar
precauciones adicionales cuando tienes que, ya
sabes, reutilizar los
nombres y así sucesivamente. Entonces solo uso la carcasa de camello. Puedes usar
guiones bajos, lo que sea, pero simplemente no me gustan los espacios
dentro de estos nombres Entonces voy a seguir adelante
sumar esa migración. Se va a construir el proyecto, y la compilación es exitosa, pero tengo un error. Entonces vamos a leer este error.
Y en este curso, no
voy a
rehuir los errores porque sé que mucha gente odia los errores
que obtiene en EFC A veces
no son muy claros, y es difícil solucionar
algunos de estos errores Entonces no voy a
rehuir los errores. En todo caso, voy a conjurar
deliberadamente algunos errores para que podamos
atravesarlos juntos. Pero esta es solo que
simplemente está diciendo que
el proyecto de inicio, que es la aplicación de consola, no hace referencia al proyecto de
diseño, ¿verdad? Entonces, en otras palabras, necesito
instalar un paquete
en la app de consola. Entonces, una manera fácil de hacerlo. Por supuesto, puedes
ir a New gate, pero voy a intentar
hacerlo a través del archivo del proyecto. Voy a crear un nuevo grupo de
elementos y darle una referencia de paquete para incluir microsoft dot entity
framework core design. Y solo estoy configurando
la versión que
sé que estoy usando a través
del proyecto resto. Esta versión puede variar en
función de cuándo estás
haciendo el curso. Entonces, si estás tomando este
camino, entonces está bien. Si no, siempre puedes
ir a New gate y agregar el paquete entity framework
design como lo hemos hecho para todos
los demás paquetes. El siguiente
paso muy importante es
asegurarnos de que tenemos nuestro proyecto de
datos seleccionado. Acabo de ver una lista
para borrar el ruido y los errores en la sección, pero solo quiero
señalar que
necesitamos que el proyecto predeterminado aquí sea cualquier proyecto en el que
tengas el contexto DB, para nosotros, esos son datos. Voy a
seguir adelante seleccionar datos, y luego voy a
simplemente presionar hacia arriba arco lo que me trae sobre el comando add migration initial
migration. Adelante y
vuelve a intentarlo y esta vez, tenemos nuestra migración creada. Ahora, echemos un
vistazo a lo que tenemos aquí. Tenemos nuestra carpeta
llamada migraciones, y tiene al menos un archivo ahí con el nombre de la
migración que le dimos Observe que hay una
marca de tiempo en él. También tenemos esta otra
que es la instantánea de contexto. Entonces básicamente, en
este momento, es como se verá la
base de datos, y tenemos nuestro archivo de migración. Tomemos un tiempo para apreciar exactamente lo que
hay en un archivo de migración. Entonces normalmente en SQL, habrías escrito sentencias
SQL, crear tabla, crear, bueno,
lo siento, crear base de datos,
luego crear tabla. Entonces pones en todos los
campos y las restricciones. Si estuvieras escribiendo un guión. Si estuvieras usando el estudio de
gestión, habrías estado haciendo clic y todo eso se habría
generado en segundo plano. Bueno, un archivo
de migración va
a ser prácticamente una representación
de todas esas acciones, pero con C contexto agudo y construido sobre lo que llamamos el patrón constructor, ¿verdad? Entonces, si solo le echas un
vistazo,
se ve complicado, pero simplemente siéntate
, respira hondo y míralo como desarrollador, notarás que
todo lo que te está diciendo
tiene sentido, ¿verdad? El constructor de migración, que es un objeto que
se pasa aquí, crear tabla. Nombre fuera de la mesa,
fugas, ¿verdad? Y luego automáticamente
va a asegurarse de
que crea. Entonces, aunque en
el contexto DV, yo había sugerido, perdón, solo
estoy tratando de
decir mucho aquí. Yo había sugerido inicialmente
que cuando estamos creando los modelos de clase, comenzamos
con los que menos dependencia tienen. Porque si empezáramos con equipo y equipo
tendríamos una dependencia esta propiedad de navegación para liga y liga
no existió entonces, esto hubiera sido
un pequeño error Por lo que hubiera sido prudente
de nuestra parte crear liga. Entonces la liga ya está ahí cuando estemos creando
cosas que necesitan liga. Bien. Ahora bien, en el contexto DB, no necesariamente
seguí ese orden. Simplemente básicamente los enumeré
al azar. Entonces no necesariamente
los enumeré en el orden en que
quería que se crearan
porque obviamente, hubiera querido que se
crearan ligas antes que los equipos. No obstante, si se mira
en la migración, ya pasó
y vio que ligas no
tiene claves foráneas, Teams sí. Así que las ligas tienen que ser
creadas antes que los equipos lo hagan. Eso es más o menos
lo que acaba de hacer FCR. Entonces es crear
la tabla de liga. Le está dando las
columnas ID y nombre. Y si se mira de cerca una
vez más, siguiendo las convenciones de
nombre, ID automáticamente
va a ser un int, no anulable, y es un incremento automático de identidad de servidor CQL Todo eso se generó porque usamos la palabra o
el nombre ID para esta columna. FOR inferimos que esto es lo que queríamos
como nuestra clave principal Y entonces verás
aquí donde está diciendo que el tipo de columna es cadena. Ese es un tipo C sharp, pero luego en la base de datos, lo
estamos haciendo NTR ¿Todo bien? Solo deja
que eso se empape un poco. Entonces seguimos adelante y
agregamos las restricciones que realmente hacen de
esta la clave primaria, que es I la columna ID. Entonces repite esas acciones. Constructor de migración, crear tabla, crear equipos, crear las
columnas, una vez más, inferir cuál es la clave
primaria, y luego agregar el ID de
liga como un int, Pero luego va un paso más allá con las
restricciones donde
crea la clave primaria y
crea la clave externa, que está vinculando el ID de liga de
columna a las ligas de tabla principales
y el ID de columna principal Entonces ves que todo eso se infiere cuando usamos nuestras convenciones de nomenclatura
adecuadas Puede haber
momentos en los que tengas que, ya
sabes, salirte del rumbo,
y eso es comprensible, pero no dejes que sea
un caso en el que
siempre vas a estar
haciendo lo tuyo y luchando contra QR, y luego terminas haciendo el
doble de trabajo cuando QoR está más que feliz de
hacer todo el trabajo por ti Entonces, después de crear todo
eso, sigue adelante y crea un índice en esa columna de clave
externa. Ahora también
notarás que
hay dos Lo siento por eso, hay dos métodos dentro
de este archivo de migración. Tenemos arriba y hemos
hecho más o menos medios cuando estoy actualizando
la base de datos o
actualizando la base de datos, esto es lo que quiero que se haga. D significa que si voy a deshacer esta migración
de la base de datos, esto es lo que se debe hacer. D igual que arriba es opuesto a D, el código que está en up va a estar haciendo
algo completamente contrario al
código que está en do porque hay momentos en los que
haces un cambio de base de datos, y luego dices, Oh, eso no es realmente lo que quería hacer,
entonces haces un cambio. Pero entonces cuando se quiere
hacer ese cambio, a veces es más fácil
decirlo que hacerlo. Entonces al menos FCR está diciendo, bueno, yo estoy diciendo a la base de datos qué hacer cuando se está haciendo la
migración, y también voy a
decirles qué no hacer
o qué hacer cuando esta
migración se está deshaciendo Entonces todo eso está automatizado
dentro de este archivo. Bien. Bien, entonces ahora
que tenemos la migración. Vamos a terminar esta
lección ejecutando el
comando más mágico y probablemente el mágico y probablemente el
más importante de todos ellos, que es actualizar la base de datos. Entonces, hasta ahora, todavía
no tenemos nuestra base de datos. Seguimos adelante y tecleamos
actualizar base de datos de guiones. Presiona Enter, deja que se construya. Y lo que
hace ese comando es mirar las migraciones
que probablemente
conoce y luego mira migraciones de las que
no conoce, y luego simplemente
recoge a partir de ese punto y ejecuta las
migraciones en el futuro Aquí lo ves dice
aplicar migración, y luego
me está diciendo qué migración
aplicó si hubiera cinco habría aplicado cinco, pero solo hay una,
así que me está haciendo saber que lo ha hecho
con éxito. Entonces, cuando mire hacia atrás
en mi lista de bases de datos, ahora
veré la base de datos por el nombre que había definido
en esa cadena de conexión, núcleo EF de liga de
fútbol. Cuando amplíe las tablas, voy a ver el historial de
migración de EF, que básicamente es una
tabla en la base de datos, haciendo un seguimiento de la migración. Para que puedas decir hasta qué
versión es tu base de datos. ¿Verdad? Y luego tienes
ligas y nosotros tenemos equipos. Y si miras, ves llaves, Bien, entonces esa es
la clave primaria. Y ves aquí que el ID de
Liga es una clave foránea. Todo eso se configuró en la base de datos para nosotros
cortesía de esta migración. Ahora, en la siguiente
lección, vamos a ver cómo
podríamos haber escrito esta migración porque posible que no necesariamente quieras ejecutar base de datos de
actualización y
eso y dejar que FCR tenga dominio completo sobre
todo en Pero hay una manera de que
podríamos haber generado un script SCO basado en
estas instrucciones, y entonces podrías
ejecutarlo por tu cuenta. Entonces, cuando
volvamos, veremos eso.
7. Generar scripts de migración: Chicos, bienvenidos de nuevo.
Entonces en esta lección, vamos a hablar sobre el
scripting de nuestra migración Entonces, el estudio de caso de
por qué querrías crear scripts en lugar
de, ya sabes, generar un
archivo de migración y hacerlo desde el administrador de paquetes sería quizás solo separación
de controles. A lo mejor hay un administrador de
bases que se encarga de los cambios en la
base de datos. Entonces tú el desarrollador, no
estarías haciendo
estos cambios en la base de datos, pero has hecho la migración
contra tu local. Hay que entregárselo para
que lo pueda hacer en
el medio ambiente. Ya sabes, hay
diferentes situaciones que podrían determinar si puedes o no hacerlo la manera que acabamos de
hacerlo en el video anterior. O tendrías que escribir la migración y entregarla. No obstante, vamos a aprender a escribir
la migración, y es un procedimiento muy
sencillo. Entonces solo tenemos una migración, por lo que el guión no será
el más complicado. medida que el script crece, hay comportamientos
particulares que
se agregan en consecuencia, y el script crece con las diferentes migraciones, ¿verdad? Entonces más adelante, podemos volver a visitarlo
, pero ahora mismo, solo
queremos ver cómo
guiaríamos esta migración Entonces en la
consola del administrador de paquetes, es bastante simple. Solo dices migración de guiones de
guiones. Lo que va a hacer
es la compilación regular, y luego va a generar el archivo SQL que corresponda
con todos estos comandos. Ahí vamos.
Verás aquí que está comprobando si la tabla del
historial de migración es nula, luego sigue adelante y
crea esa tabla. Entonces iniciamos la transacción, creamos las
tablas en consecuencia. Obtenemos el índice, insertamos en el historial de
migración, la migración que acaba ejecutada, ¿verdad? Eso es. Entonces, una vez más, esto
probablemente se va a
hacer cuando quieras entregar la responsabilidad de los cambios de la base de datos
o
la creación de la base de datos, sea lo que sea, a alguien más tu equipo en
la organización, y eso es lo que FCO permite
8. Base de datos existente de Ingenier inverso: Oigan, chicos, bienvenidos de nuevo.
Entonces en esta lección, vamos a estar
viendo cómo podemos realizar ingeniería
inversa en una
base de datos que existe. Entonces, una vez más, tenemos
código primero donde
podemos escribir el código que
genera la base de datos. Pero en algunas situaciones, es posible que ya
tengas una base de datos que deseas instalar en tus modelos de clase como lo que hemos estado
haciendo hasta este momento Entonces en esta lección, vamos a
estar viendo eso, y ustedes habrían tomado nota que ya he
creado un nuevo proyecto. Entonces puedes hacer esto si
quieres seguir adelante, pero no es absolutamente
necesario porque
solo vamos a
mirar el comando y ver exactamente qué hace. Así que he creado este
nuevo proyecto de consola up, que es únicamente
con el propósito de andamiar el DB, para que puedas ver
exactamente lo que sucede Entonces voy a convertirlo en
mi proyecto de puesta en marcha, y vamos a ir
al encargado de paquetes. Y como repaso, voy a decir que busquen ayuda, y vamos
a echar un vistazo al comando para
andamiar
la Entonces aquí está la lista
de los comandos, y vemos aquí que podemos
decir contexto de andamio DB Entonces ese es al que
vamos a estar prestando atención en esta lección. Entonces cuando queremos andamiar, solo
voy a copiarlo y pegarlo como el siguiente
comando que voy a ejecutar,
y vamos a usar la
misma base de datos en la que estamos trabajando en
todo este curso, que es nuestra base de datos de
liga de fútbol Voy a andamiarlo
en las maquetas, ¿verdad? Entonces necesito especificar
el proveedor. Así proveedor de hyfen. Entonces este es un parámetro. Proveedor, y nuestro
proveedor será microsoft punto tit framework
core dot SQL server. ¿Todo bien? Entonces ese es el nombre
de nuestro paquete, y ese es nuestro proveedor. Así que eso solo va a mostrar que este
comando de contexto de andamio DB podría ser utilizado para otras bases de datos que
no son necesariamente servidor SQL Todo bien. Entonces
especificamos el proveedor, y luego vamos
a tener que darle la conexión, toda la conexión,
aquí estaría la misma conexión
que estamos prácticamente usando en nuestro contexto B. Entonces solo hay que formular
una cadena de conexión. Como ya tengo uno, no
voy a
escribirlo desde cero. Sólo voy a copiarlo
porque como dije, estamos usando la misma base de datos. Pero sea cual sea la base de datos que sea, escribes una cadena de conexión. fuente de datos es igual
al servidor, está en el catálogo inicial es igual al nombre
de la base de datos, ya que podría estar en un
servidor en otro lugar. Puede que no necesariamente
esté en el mismo servidor. Entonces solo quieres tomar nota
del hecho de que
escribes esa cadena de conexión
según donde esté esa base de datos. Entonces voy a abrir
comillas, poner en mi cadena de conexión. Cerrar comillas. Entonces una cosa más
que queremos hacer antes de intentar
ejecutar este comando. Queremos asegurarnos de
que nuestro proyecto haga
referencia a las mismas
bibliotecas que tuvimos que
instalar cuando estábamos haciendo nuestro andamiaje inicial o nuestras migraciones
iniciales, Entonces, si echamos un vistazo
atrás en los datos, vemos que teníamos que hacer
referencia al servidor kill, y tuvimos que hacer referencia a las herramientas y herramientas
referencias diseño. Todos estos son
necesarios. Yo sólo voy a tomar
todo este grupo de artículos. Copia y luego pasa a nuestro nuevo proyecto y pega
y luego haz una compilación rápida. Y luego después de que eso
haya sido exitoso, vamos a volver a
la consola del administrador de paquetes. Sólo voy a verificar
dos veces que el proveedor es correcto y
la conexión es correcta. Voy a asegurarme de
que el proyecto por defecto o el proyecto objetivo es el proyecto al que queremos
hacer los andamios Y luego voy a
presionar enter. Todo bien. Y después de presionar Enter, el edificio
me dio una t advertencia y luego una excepción muy mortal. Ahora, como dije, no
voy a rehuir los errores
en este curso. Creo que ver los errores y resolverlos es muy importante. Entonces este error está diciendo que un error relacionado con la red ha producido
un error relacionado con la red
al intentar conectarse al servidor. Entonces eso significa que algo anda mal con mi cadena de conexión. Y creo que sé lo que es. Es la doble slash porque tenemos que usar
la doble slash escribir la cadena de conexión en el contexto literal aquí Pero entonces en lugar
del gestor de paquetes, no
necesito ese doble slash Voy a quitarlo, y después voy a intentarlo de nuevo. Y esta vez, no tengo ningún error. Recibí la misma advertencia,
pero no tengo ningún error. Y si echas un vistazo detrás de
mi consola de monitor de paquetes, y dentro del proyecto,
vas a ver aparecer
un montón de archivos. ¿Todo bien? Entonces echemos un vistazo a lo que representa
cada uno de ellos. Así que sólo voy a
colapsar cualquier cosa que no sea absolutamente necesaria. Y luego echemos un
vistazo al contexto. Por lo que generó un archivo de contexto. El mismo archivo de contexto
que creamos manualmente, solo para generarlo. Le dio el nombre
basado en la base de datos. Le di la herencia
del contexto DB, tiene dos constructores,
un parámetro s,
uno con el parámetro aceptando opciones de algún lugar de
alguna otra aplicación,
está bien Tenemos nuestros conjuntos de bases de datos tanto
creados como virtuales, y luego tenemos el mismo método de
desconfiguración, ¿verdad? Entonces, si hice una comparación lado
a lado, como que ves que mientras mía es mucho más o siempre
está mucho más simplificada. Realmente es lo
mismo, ¿verdad? Tenemos la desconfiguración,
y luego dice, si no hay
opciones configuradas, entonces pone en esa
cadena de conexión tal como lo hicimos nosotros No obstante, sí
nos da esta advertencia, que es la misma
advertencia que vimos en la consola del administrador de paquetes. Es solo decir que
quieres evitar poner tu cadena de conexión directamente dentro del contexto así. Y como dije,
estamos haciendo esto provisionalmente porque
es solo una aplicación de consola, así que solo la estamos poniendo
ahí justo para que funcione Todo bien. Pero en una aplicación
más grande, viviría en otro archivo
y se pasaría bajo demanda. También tomarás nota
de otro método, que aún no hemos
mirado del todo, pero como dije, puedes anular la
mayoría, si no todos, los métodos que vienen estándar de la clase
de contexto DB, y este otro método
está en la creación de modelos. Entonces éste
básicamente es solo decir que tenemos la anación
la cotejo relacional estableciendo los conjuntos de caracteres que vamos a usar
para esta base de datos, y luego continúa diciendo que el equipo de
entidad punto constructor de
modelos tiene índice,
y tiene una liga
con muchos equipos y tiene un extranjero recuerda que solo seguir la
convención de nomenclatura cuando estábamos creando
la base de datos, implicaba todo esto para nosotros o
lo hacía en la migración. Ante esta situación, se trata de
mirar una base de datos existente, y luego está tratando de
formular las reglas en la creación esta base de datos existente
o de interactuar con
ella
a las que hay que adherir. Todo bien. De la misma
manera si cambiáramos el nombre de esta base y luego te
dijéramos
que hagas una migración, en realidad
miraría todas estas reglas
para saber cómo hacer una migración para una
nueva base de datos que se ve idéntica a la
que está andamiada. Entonces es un muy te lo estoy diciendo, FCR es muy, muy inteligente
y está haciendo mucho Es jalar muchos hilos
en el fondo para ti. Bien, así es como se ve
realmente el contexto DB. Y luego si echamos un vistazo a nuestras clases que se generaron, ve
que obtenemos
una clase parcial, obtenemos hash set que representa
la colección de equipo. Entonces voy a llegar a eso en un minuto. Pero obtenemos ese constructo y
obtenemos las mismas propiedades. Y si estamos buscando equipo, se ve prácticamente
igual que como hicimos el nuestro propio. Entonces eso significa que estamos en
el camino correcto, ¿verdad? Todavía tenemos esa clave
foránea y la propiedad de navegación
hacia la liga, que también es virtual Ahora, solo dando marcha atrás a
lo que tiene la clase de liga, vemos aquí que tenemos
una propiedad adicional que no pusimos en la nuestra propia Entonces sólo voy a sacar a
colación la liga original. Este es el que
creamos, ¿verdad? Y entonces el que estaba andamiado tiene esta propiedad
adicional, que es una colección de equipos Ahora bien, el concepto aquí es
que es uno de demasiados. Eso lo sabemos. creamos, y luego
repasaremos una demasiadas, pero solo quiero
destacar que
lo que está haciendo aquí es decir que una liga
tendrá acceso a muchos equipos. Un equipo, pertenece a una liga. Pero una liga tiene muchos equipos.
Ese es el uno a muchos. Entonces con esta
propiedad de navegación establecida para ser una colección o podría
haber sido una lista o
bien, usó colección por defecto Cuando estábamos creando,
podríamos haber dicho lista, podríamos haber dicho yo numerable Pero el punto es que es el acervo de
artículos relacionados con esta entidad. Entonces con tan solo conseguir una liga, podría incluir a
todos los equipos, y eso me ahorraría el dolor de tener que
hacer dos consultas separadas, perdón, para conseguir los equipos y la liga con la que
están relacionados Bien, entonces es
algo muy poderoso hacerlo así. Entonces más adelante podemos agregar esa
propiedad de navegación a la nuestra, pero solo quería
resaltar qué exactamente se estaba andamiando
y qué se está haciendo exactamente Y más o menos eso es todo para
andamiar en la base de datos. Hay otras pequeñas cosas
que probablemente puedas hacer, pero en el nivel más básico, si hay una base de datos, tal vez comenzó a
construir un servidor sc, o es parte de un proyecto
heredado o un sistema heredado y
quieres reelaborarlo, solo
quieres empezar a trabajar en él sin empezar
de cero Entonces puedes usar este comando, traer o esa base de datos en
forma de estos modelos. Y luego a través del contexto, solo
puedes empezar a trabajar con él fuera de la puerta. Bien. Bien.
9. Ver el diagrama con herramientas básicas de Entity Framework: Oigan, chicos, bienvenidos de
nuevo en esta lección, vamos a echar un vistazo las herramientas eléctricas de FCO
y cómo pueden ayudarnos a visualizar nuestra
base de datos a través de Visual Studio Ahora bien, esto me viene de
los talones mostrando un diagrama de base de datos
antes donde
estábamos en el SQL Server Management
Studio y generé ese diagrama cero solo para representar la base de datos que estábamos
tratando de construir en ese momento Puede que no necesariamente
tengas ese lujo, y no estoy diciendo que necesites
ir a buscar el estudio de
administración,
pero usando las herramientas eléctricas de EFC a través de Visual Studio, eres capaz de generar un diagrama
similar y ver cómo
FCO visualiza tu base de datos
o cualquier base de datos a FCO visualiza tu base de datos
o cualquier base la que se esté
conectando Así que comencemos. Si tienes Visual
Studio, eso es bueno. Simplemente vas a extensiones, vas a administrar extensiones. Y cuando surge ese diálogo, solo
buscas herramientas eléctricas de
FCO, y cuando veas en
los resultados de búsqueda, solo
tienes que seguir adelante
y presionar descargar Bien. Después de eso, tendremos
que reiniciar Visual Studio, para que puedas seguir adelante
y hacerlo rápidamente. Ahora, después de cerrar
Visual Studio, el gestor de extensiones
va a subir y
terminar la instalación. Si aún no tienes esta característica del
editor DG ML instalado, que probablemente se instaló
con Visual Studio, por lo que es posible que no tengas que
pasar por este paso. Pero si estás
pasando por el paso, entonces no hay problema. Sólo tienes que seguir adelante y
presionar modificar
permitirle traer las dependencias. Y una vez hecho ese procedimiento, se puede volver a abrir Visual
Studio y luego lo que
vamos a notar es cuando
hacemos clic derecho en un proyecto, vamos a ver
un nuevo elemento del menú en forma de herramientas eléctricas FQ Entonces verás una
serie de opciones,
algunas de ellas parecidas lo que hemos estado discutiendo
hasta este momento con las diferentes
migraciones y
andamios e ingeniería
hacia adelante, todas esas cosas son
realmente posibles a través de estas herramientas eléctricas FQ sin la necesidad de
escribir los Sin embargo, para esta lección
en particular, lo que quiero enfocarme es en
agregar el diagrama de contexto. Entonces claro, una vez más, queremos asegurarnos de que estamos en un proyecto que tenga
el contexto DB. Vamos a hacer click derecho,
ir a FC Power Tools, y luego diremos Agregar diagrama de contexto
DB. Y luego va a
generar un nuevo archivo con una extensión dot DGML y
vamos a conseguir nuestro diagrama Entonces pensé que
sería capaz de seleccionar, pero en realidad es solo
arrastrando por todas partes Entonces ves aquí, nos está dando este contexto DB en
forma de diagrama,
dándonos el equipo, las
diferentes propiedades, y podemos hacer clic o pasar el cursor sobre la propiedad para obtener un poco
más de información sobre ella Es la clave principal, y no es notable. Ves todas esas
anotaciones o todos
los meta datos están disponibles aquí
mismo en hover Y si pasamos el cursor sobre la mesa, es más o menos lo mismo Así que desde visual studio, podemos utilizar esta
herramienta para visualizar exactamente lo que está sucediendo en nuestra base de datos en cualquier momento dado. Ahora, dado que sólo
tenemos dos mesas derechas. Ahora bien, este diagrama
podría no parecer tan emocionante como
probablemente podría ser. Pero solo puedes tomarte
un tiempo para mirarlo. Puedes mantener el
control y desplazarte para acercar un poco o
simplemente puedes cambiar el
zoom arriba arriba aquí, y puedes echar un vistazo a la leyenda donde
señala cuáles son
los diferentes símbolos o
los diferentes colores,
ves aquí, el rojo representa
una propiedad de navegación. El Qué es ese
púrpura o azulado, lo siento, soy
un poco daltónico,
pero este color purpúreo
representa las claves foráneas,
y luego las
claves primarias resaltadas, y luego las diferentes Entonces puedes tomarte un tiempo
para simplemente llevarte ya sabes, asimilarlo, puedes ver los diferentes tipos
de relaciones. Pero a medida que nuestra base de datos crece, revisaremos esto y echaremos
un vistazo a cómo infiere FCR, qué tipo de relaciones y diferentes anotaciones
sobre diferentes propiedades a
medida que avanzamos, y luego podremos ver este diagrama evolucionar con nuestra base de datos. Bien.
10. Añadir el registro verbo: la carga de trabajo de EF: Oigan, chicos, bienvenidos de
nuevo. Entonces en esto menos, vamos a estar
configurando FCR con algunas opciones adicionales para escupir más detalles
sobre lo que está Entonces COR es realmente
bastante por defecto, pero queríamos hacer algo de ruido porque cuando estamos
ejecutando nuestros comandos, quiero que tengamos una representación
visual de la Q que se está
orquestando y las
diferentes operaciones se
están realizando
en segundo plano mientras hacemos lo nuestro Entonces lo que vamos a hacer aquí es extender el
generador de opciones para saber que necesita iniciar sesión Y voy a dejar que inicie sesión
para consola esa línea derecha. Entonces porque estamos usando una
consola arriba está a la derecha. Entonces nos registramos para consolar
esa línea derecha. Y voy a agregar a la
configuración o digamos, el pipeline de
lo que debería ser el registro. Quiero que logre el nombre del
comando de categoría DB logger para que podamos ver una
representación
de visor de lo que se está haciendo exactamente. Y voy a
extender eso para que
sepa que queremos un nivel de registro. Iba a decir un nivel de registro. Información de puntos. Y creo que voy a tener que
incluir van a ir a incluir una biblioteca para
extensiones de punto de Microsoft dot logging. Creo que me
adelanté hace un momento. Entonces es nueva categoría DB logger, y luego cerramos aquí una llave
rizada. Y luego tenemos la información de nivel de
registro, y luego cerramos ahí el
paréntesis Así que échale un vistazo a esa
línea. Pida disculpas por eso. Así que nos registramos a la consola punto línea
derecha, nueva matriz, y luego sólo estamos pasando en la
línea de nombre de comando allí mismo, DV logger categoría
base de datos nombre de comando, y
le estamos haciendo saber que
queremos un nivel de registro de información. Entonces eso significa que todo
lo que está haciendo
queremos estar viendo escupir
a la consola Otra cosa que
voy a incluir es habilitar el registro de
datos confidenciales. Eso nos permite ver
o le dice a FCR que
todo lo que está sucediendo en segundo plano
que probablemente no
querría que
viera su usuario front-end, nosotros queremos verlo Es nuestra app la que estamos aprendiendo, así que al menos podemos hacer
esto con cero riesgo, pero no necesariamente
querrías hacerlo en un servidor de
producción, pero sí ayuda con la depuración
en ciertas situaciones Entonces ahora que tenemos
todo esto cableado, voy a simplemente
saltar a la consola. No necesariamente
tienes que hacer este paso. Yo solo
escribí algún código para que podamos empezar a
interactuar con el curso F, para que puedas ver exactamente a qué equivaldría
todo eso. Pero en los próximos videos, estaremos revisando
todo este código juntos. Pero por ahora, solo
quiero que vean una muestra de la tala
adicional. Entonces, en pantalla, verás
la aplicación de consola. Y si miras de cerca, verás que
se escupen los troncos Entonces tenemos información en
ese sello de tiempo. Hicimos este comando, y luego te está
mostrando que
ejecutamos un comando DB,
el parámetro era. Entonces, lo que pasaría
naturalmente si
no habilitamos el registro
sensible es que estos parámetros, no
verías los valores. Entonces, habilitar el
registro sensible, como dije, mostrará algunos detalles que se
habrían quedado fuera por, ya
sabes, razones de seguridad, ahí el
registro sensible al título, ¿verdad? Entonces podemos ver exactamente qué
valores se están pasando, y el tamaño del valor, el tipo, el tiempo de espera del comando, y luego vemos que el SQL
real que se está generando
insertar en esa tabla, los valores, y luego
solo está tomando ese parámetro. Entonces no es poner
ese valor directamente. Entonces eso solo va
a demostrar que FCR está haciendo
parametrización activamente, que es un componente clave para la lucha contra la inyección
SQL como una laguna de seguridad que mucha gente intenta Entonces es parametrizar
la consulta simple, y luego simplemente sigue
adelante y selecciona el ID de ahí y
actualiza la identidad del alcance Pero ahora mismo,
no voy a entrar en demasiados detalles sobre
lo que está haciendo el guión. Solo quiero destacar
que ahora estamos en una posición que cuando
vamos a estar escribiendo nuestros comandos FC, podemos ver activamente el SQL que se está
generando en segundo plano. También vemos el tiempo de ejecución
esto a 61 milisegundos. Pero puede haber ocasiones tal vez una consulta se esté ejecutando
demasiado y te estés preguntando por qué probablemente
necesites modificarla Todas esas cosas que puedes
hacer cuando tienes este tipo de tala a tu
disposición. Bien.
11. Operaciones sencillas de insertos: Bien. Oigan, chicos, bienvenidos de nuevo. Entonces, en esta lección,
vamos a echar un vistazo a cómo podemos realizar insertos simples y
seleccionar res usando EF COR. Ahora, saliendo de nuestra
lección anterior donde miramos el registro detallado y agregando
información adicional a la consola Habrías visto que tenía
este pedacito de código que
estamos para explorar y
tratar de entender. Entonces la primera línea que
quiero señalarles, y esta es una vez más,
el programa dot CS archivo en nuestra app de consola. Todo bien. Entonces la primera línea que
quiero señalarles es donde estoy instanciando
nuestro contexto DB Entonces tengo contexto DB privado estático
de liga de fútbol. Y por si acaso te estás preguntando de dónde viene
ese nombre, ese es el nombre de
nuestro contexto DB aquí. Recuerden que
dije que este archivo representa la conexión
a la base de datos. Tiene la
cadena de conexión, y
bueno, conoce los elementos o las entidades más bien
en la base de datos. Entonces toda esta clase a medida que nuestra
base de datos crece nuestros contratos, esta clase es la
que nos da esa puerta de acceso a la base de datos y nos permite interactuar con las
diferentes entidades. Entonces tenemos que tener un
objeto instanciado de ello. Ahora bien, en un núcleo regular dot nic, bueno, déjame no decir núcleo
regular dot nic. En una aplicación de
núcleo punto nic más grande como una aplicación web o incluso
una aplicación blazer, no
verías que
se haga de esta manera. Lo verías
siendo inyectado en. Pero una vez más, estamos aquí para aprender sobre la
sintaxis de F core. Entonces estoy tratando de no enfocarme en esos otros aspectos del desarrollo en este curso en
particular. Todo bien. Entonces estamos instanciando o contexto DB de liga
de fútbol. Estoy llamando al contexto del objeto. Habrías visto diferentes
sugerencias dadas a ti, que puedas elegir la que creas que sea
más indicativa de lo que este
objeto necesita representar Pero contexto es casi como
la palabra universal para significar el archivo que
me conecta a la base de datos, ¿verdad? De ahí usarlo en el nombre de la clase e incluso
el nombre del objeto. Una vez más, el nombramiento
es más subjetivo. Entonces eso está bien si
tienes otras ideas. Entonces simplemente lo instanciamos aquí. Y luego pasamos a la principal. Entonces, como
lo hicimos en la clase, esto es global para cualquier
otra función que vamos a usar
dentro de este archivo de clase. Ahora, para agregar algo
a una tabla, la sintaxis sería contexto. Una vez más, ese objeto que representa una conexión
a la base de datos. Entonces decimos contexto, punto. La mesa con la
que esperamos interactuar, y esta palabra ligas está realmente relacionada con lo que
llamemos las mesas aquí. ¿Todo bien? Entonces eso es ligas. Entonces si solo
reescribo esto desde cero, voy a decir contexto, punto, quiero ver
un montón de opciones Puedo agregar, puedo agregar una sincronización. Puedo hacer varias cosas, pero luego verás las
diferentes propiedades, y algunas de las propiedades
incluirían los nombres de las tablas. Hay ligas, y si me desplazo un poco
más hacia abajo, hay equipos. Así que tantos conjuntos de bases de datos como hayamos definido en el archivo de contexto, logramos acceder a ellos
directamente aquí mismo cada vez que necesitamos
interactuar con dichas tablas. Entonces contextualizar ligas, y luego qué quiero hacer
con la tabla de liga. Ante esta situación,
quiero añadir. Ahora bien, si echamos un
vistazo a la función ad, verás aquí que
la sobrecarga está esperando el pozo,
no la sobrecarga. El parámetro que
se espera por la función ad más bien
es de tipo liga, y solo está diciendo que
espera una entidad de liga. Entonces en otras palabras, espera algún objeto del tipo liga. Así que esa es la belleza de la
cancha F nos permite mantenernos en C aguda porque en la sintaxis Q, habríamos tenido que
escribir algo así como insertar en ligas, y luego valores y luego enumerar los valores y eso es si no
vamos a especificar las columnas y luego los valores. Y sí, esa sintaxis
sería que tiene un propósito, pero teniendo que ponerla en la C sharp y luego convertirla
y luego hacer todo eso, FC solo está diciendo
permanecer en C sharp, tengo el contexto del objeto Me sale la tabla que quieres agregar, y luego me das los
datos que quieres agregar. Entonces agregué aquí una
liga de futbol de Jamaica, pero luego podemos cambiar esto y probemos la
Premier League inglesa. Todo bien. Entonces nueva Liga
instanciando un objeto, y estamos pasando
en las propiedades, y League realmente
solo tenía nombres de identificación Entonces, debido a que ID ya es
un incremento principalmente, no
tenemos que proporcionar
un valor para el ID Podemos acceder a él con seguridad, pero no necesitamos aportar un valor cuando estamos
agregando. Todo bien. Entonces sigamos adelante y ejecutemos este comando y
veamos qué pasa. Los registros aquí
nos está mostrando que ha ejecutado
con éxito
este comando, tardó 112 milisegundos y puso en los
parámetros y todo Y entonces aquí está la
sintaxis CQL que se generó. Entonces inserte en ligas, luego los nombres de las columnas,
luego los valores, y luego el valor,
y luego simplemente actualizó ese objeto en consecuencia. Ahora, otra línea que
quiero señalar es la línea 14, que es la línea definitiva a la
que hay que llamar. No importa lo que hagas, pensando que estás interactuando
con la base de datos. Una vez que estás manipulando datos, es
decir, estás agregando o estás actualizando datos o borrando datos, tienes que llamar a cambios seguros porque todo este método lo hace y los métodos similares para
la actualización y la eliminación Todo lo que realmente hacen es rastrear
qué cambios tienen que suceder, pero
los están rastreando en la memoria. ¿Verdad? Entonces,
mientras la aplicación esté procesando esta operación en
particular, es solo rastrearla
en la memoria que, bien, sé que necesito agregar esto.
Necesito actualizar esto. Necesito borrar eso. Pero
luego hasta que guardes los cambios, guardar los cambios en realidad
dice, generar el SQL, enviar a la base de datos
e intentar esto, y luego vamos a
revertir si algo falla y le haremos
saber al usuario lo que pasó. ¿Todo bien? Entonces para eso es realmente para
lo que están los cambios de guardado. Y luego llamamos
guardar cambios A sync, pero luego también está el guardar cambios sin
el AC eso está bien. Lo usaré sin el AC ya que esta no es una función
asíncrona Simplemente lo voy a mantener simple. Pero una vez que estés usando programación
asíncrona, siempre
puedes usar la
versión A sync de estos métodos cuales, por supuesto, tienen que ser colocados en un método
asincrónico Así que acabo de cambiar todos mis métodos a las versiones de sincronización
A, y cambio la
función principal en una tarea de sincronización A. Y luego por eso, ahora puedo tengo que decir
un peso agregar una sincronización, peso, guardar cambio es una sincronización. Ahora, otra cosa, solo
quiero romper
esto un poco más. Porque aquí mismo estoy agregando el objeto
directamente al parámetro. Tal vez no
siempre sea así, porque sobre todo en aplicaciones
más grandes, como cuando un usuario está
enviando el formulario, luego en una aplicación web,
ellos envían el formulario, obtendrías todos los
datos del formulario en un objeto que necesitas
pasar a la base de datos. No necesariamente
querrías obtenerlo del formulario y
luego tener que escribir nueva liga y luego intentar poner cada propiedad
con cada valor de nuevo. Así que siempre puedes simplemente inicializar Subq Sevar
League es igual a, y luego puedo inicializar
una nueva Déjame hacer esto para
reducir cualquier mecanografía larga. Ahí vamos. Y entonces le
puedo dar esta liga. Se nota que soy fanático del
fútbol, ¿verdad? Entonces La Liga. Entonces esta
sería la liga española. Ahora que tengo mi objeto que representa la liga que
deseo agregar a la base de datos, ahora
puedo decir agregar AC y
pasar ese objeto. Entonces es realmente así de simple. Puedes construir tu objeto
en otro lugar, luego agregarlo, y luego cuando guardas los cambios, es
decir cuando lo haces
comprometido con la base de datos. Ahora bien, lo que quiero
señalarles también es que una vez que
guardemos los cambios, este objeto se va a actualizar
automáticamente
con su nuevo valor. Entonces déjame agregar un
punto de interrupción y correr. Y lo que voy a hacer aquí
es iniciar una ventana de vigilancia, y voy a poner ahí el
objeto de liga para que podamos rastrear sus valores a medida que
paso línea por línea. ¿Todo bien? Déjame prender esto, hazlo un poco más grande
para que podamos verlo. Entonces primera línea, aún no ha
pasado nada. La liga es nula. Entonces voy a dar un paso
Y entonces verías que g tiene un ID de cero
y el valor Liga. Y luego va
a guardar los cambios, y luego damos un paso una vez más. Y si miras el objeto, verás que ahora
tiene el valor ID. Entonces esto es
útil cuando tienes operaciones que están
encadenadas, ¿verdad Porque es posible que tengas
una operación donde necesites agregar algo
a la base de datos, y luego necesitas ese valor, ese nuevo valor
de ID para tal vez mostrar los detalles de este
registro en la página siguiente. Entonces envío un formulario, editas a la base de datos, luego me traes a la
página para ver los datos. Acabo de enviar lo que está
leyendo de la base de datos. Bueno, aquí es donde
eso me resulta útil porque entonces puedo
consultar la base de datos directamente en ese ID de registro justo después de que la
operación haya finalizado. Sólo voy a presionar F cinco para continuar con la ejecución. Y una vez más, vemos nuestro mensaje
muy amable aquí diciendo que ha agregado
esos datos a la base de datos. No, solo por el
bien de la representación, como dije, queremos ver algunos de los
errores que podríamos obtener Lo que voy a
hacer es intentar agregar un valor de ID a este objeto antes de que se
agregue a la base de datos. Entonces sé que la identificación en este
momento era siete. Entonces voy a poner una identificación. Realmente no importa qué valor porque si
algo más que cero, cuando va a
la operación add, va a dar un error. Así que solo
quería ver el tipo de comentarios que vamos a
recibir de EFC, ¿verdad Así que solo ejecutarlo y permitirle hacer
lo que tiene que hacer. Y entonces ves
aquí está fallando, y aquí estamos obteniendo
este error. Se trata de decir que ocurrió un error. La excepción CQ no puede
insertar un valor explícito para la columna de identidad cuando la inserción de
identidad está desactivada. Entonces ya ves que estamos
obteniendo literalmente uno de esos errores que habríamos visto si
intentáramos hacer esto
en SQL directamente. Si no es el mismo error, entonces está redactado de
manera muy similar a él. Todo bien. Entonces ese es el tipo
de comentarios que EF COR nos dará
cada vez que lo intentemos. Y veremos aquí en nuestro registro de consola
que simplemente falló. Simplemente te dice que fallaste
e insertas en eso, eso simplemente falló. ¿Todo bien? Entonces, si continúo, entonces la ejecución terminará en
consecuencia. Todo bien. Entonces estamos enrollando do,
y solo quiero hacer un ejemplo más de
cómo el trabajo de marco de entidad
puede hacer la vida más fácil. Entonces en esta situación, quiero agregar una nueva liga, y estamos llamando a
esta Siria, esa es la liga italiana, y agregamos la liga como
sabemos que tenemos que hacer, luego guardamos los cambios. Pero entonces necesito información de esta liga para poder
realizar otra operación. Ante esta situación,
quiero sumar equipos. Entonces, obviamente, un equipo
necesita existir en una liga, ¿verdad? Entonces necesito la información
de la liga que se acaba de crear
para poder crear estos equipos. Entonces lo que voy a hacer es pasar este objeto de liga
a este método. Y luego notar que
tendremos que guardar los cambios
porque cada vez que estamos realizando alguna operación contra el contexto, tenemos que guardar los cambios para que surta
efecto en la base de datos. Entonces, ya
creé ese método hice una tarea de AC estática, y lo llamo agregar
equipos con ID de liga. Bueno, yo lo llamo con identificación de liga. Déjame simplemente quitarme la liga Déjame quitarme la identificación porque estoy mostrando dos
operaciones distintas en este ejemplo, y verás por qué, y está tomando un parámetro
de tipo liga, que es la liga. Todo bien. Así que solo puedes seguir
adelante y replicar eso Y luego en este método, estoy intentando algo diferente. En lugar de uno,
objeto para luego agregar, estoy haciendo una lista de objetos, y luego voy a agregar rango. Entonces esto ahora va
a aprovechar la capacidad
de los FCR para
realizar operaciones a granel Ahora, un poco de operaciones masivas de
bit tit, es una característica
que permite a FC tipo de lote múltiple, como agregar operaciones y así sucesivamente en una declaración Q
y disparar. Pero entonces el equipo decidió que, bueno, sería más eficiente
en menor número de registros simplemente hacer declaraciones SQL
individuales. Sin embargo, en cierto umbral, empezarás a ver una
instrucción SQL con toda
la información. Eso es solo un
poco sobre cómo funcionan
estas operaciones a granel en segundo plano. Pero en este método, lo que estoy haciendo es
definir una lista de equipos, y a cada uno,
le estoy dando su nombre. Entonces esto es respiraderos, y esta identificación de liga es la identificación que viene de
nuestro objeto de liga ¿Verdad? Y entonces el
siguiente equipo sería un sim siguiendo el mismo formato. Pero luego el
tercero, que es Aroma, estoy haciendo algo diferente. En lugar de usar
la clave externa, ahora
estoy usando el objeto de navegación
real y reutilizando el objeto
que se ha pasado Entonces vamos a ver
exactamente cómo funciona eso. Entonces, esta sería
la forma tradicional. Tienes la clave foránea,
pones el valor de la clave foránea, y está satisfecha, ¿verdad? Pero luego en este equipo, en lugar de usar
la clave foránea, estoy usando el
objeto real para pasar. Entonces veamos qué haría esto. Entonces voy a poner un punto de quiebre en los
primeros cambios de guardado, y luego solo
podemos pasar y ver la operación paso a paso. Así que también he añadido el reloj
para los equipos, ¿verdad? Así que permítanme dar un paso a través la liga que aún no
se ha creado. Entonces paso usa F ten, así no tengo que
pasar al contexto. Sé que tenemos nuestra identificación de ocho. Si miramos en nuestro objeto liga, lo
vemos actualizado en consecuencia. Entonces voy a
usar F 11 para entrar en este método donde ahora se definen
equipos. Sólo voy a dar un paso
por su creación. Y luego si miro en
la lista de equipos, veo
que los tengo a todos
con sus respectivos ID, y luego Roma está aquí con el objeto de navegación
Actual en lugar del ID de liga. ¿Todo bien? Por lo que el ID de liga para la Roma es cero, pero el ID de liga para todos demás es ocho como se esperaba. No obstante, la propiedad de navegación para todos los demás es nula, y para Soma, tiene su propiedad de
navegación. Ahora, veamos qué pasa
después de guardar los cambios. Sólo voy a
presionar cinco para que
podamos ver los registros
que se escupen Y se ve la primera operación de
inserción sucediendo aquí mismo
con la liga. Oh, no, eso. Este es con
la liga. Perdón, ¿verdad? Entonces vemos otro
pasando para el primer equipo, y vemos que el ID,
el ID liga de ocho
y el nombre que
se está pasando en nombre de
ID de liga, ¿verdad? Y luego para el último, se nota que es
la misma sentencia SQL. Se pone el ocho,
sabe que es Aroma, y hace el mismo
tipo de inserto. Entonces eso solo te va a mostrar que
puedes poner en el valor real de la clave foránea
y, por supuesto,
hará lo que tenga que
hacer con el inserto, o podrías poner en todo
ese objeto y aún así
inferirá eso bien, el objeto tiene su clave primaria Entonces, obviamente, este
es un objeto relacionado, por lo que la clave externa sería el objeto offset de clave primaria
y cualquier otro dato. Entonces FCR está haciendo eso por
ti en el fondo. Solo quería destacar
las diferentes formas en que se puede insertar un registro que tenga
una dependencia de clave externa. Ahora bien, hay algunas otras
cosas que puedes hacer, pero a veces solo
vienen con experiencia, pero al menos si
entiendes los conceptos básicos de cómo agregar algo
a la base de datos. Y fíjate que tuve que agregar aquí, guardar los cambios y luego
agregar nuevamente y guardar los cambios porque necesitaba que
se agregara esto para que
se generara la clave para que
pudiera llevar a cabo esta
operación. ¿Todo bien? otro lado, si hubiera hecho algo como esto y solo
tomarme el tiempo para mirarlo. Simplemente lo rediseñé para no tener que sentarme
a verme escribir Pero lo que estoy haciendo es todavía
inicializar una nueva liga, y luego tengo un equipo Este nuevo equipo tiene
nombre Bern Munich, y luego estoy pasando
en este objeto de liga Ahora tenga en cuenta, no estoy
haciendo una No estoy guardando cambios entre
estas dos líneas, ¿verdad? Entonces primera liga, equipo fresco, y está consiguiendo ese
nuevo objeto de liga. Y entonces todo lo que estoy haciendo es sumar al equipo y guardar los cambios. Y observe la diferencia
entre este anuncio y las líneas ACC del anuncio anterior. Tienes la opción, por supuesto, resaltar la mesa con la que
deseas interactuar. Entonces si dije contexto
punto ligas agregar una sincronización, y luego pasar
en un objeto de equipo, va a ser un error
automático. ¿Por qué? Porque una vez más,
la operación publicitaria requiere de un tipo
de liga, ¿verdad? Entonces no puedo estar pasando
un objeto de equipo. Por supuesto que podría haber dicho que los equipos y todo
estaría bien. Pero entonces si no
especificaba la tabla, entity framework sabría
automáticamente que, bien, este es un objeto de equipo o es una lista de objetos de equipo
como lo hicimos aquí abajo, donde acabo de decir
contexto punto agregar rango pasado en la lista de equipo. Entonces sabe que claramente
va a buscar la tabla correspondiente
para ese tipo de datos. Entonces no necesariamente tienes que al menos al tratar
con el contexto, no
tienes que especificar la tabla todo el
tiempo. Todo bien. Pero lo que quiero
señalar es que cuando hago esto y luego
hago uno guardar los cambios, en realidad
va a crear
la propiedad dependiente y luego crear automáticamente el equipo con esa clave externa. Entonces echemos un
vistazo a esa operación. Entonces cuando mires
lo que generó, verás que ejecutó el comando para crear primero
la liga. Ahí está creando
la Bundesliga, y luego obtiene ese ID, y luego sigue adelante y
ejecuta el de crear al equipo pasando en
la nueva clave foránea
a ese nuevo SCEF CR solo está tirando
de todas estas cuerdas por ti. Todo porque lo dije,
quiero un nuevo equipo, y este equipo es parte de una liga de la que no
conozco la identificación. Entonces dijo, no hay
problema. Yo tengo esto. Sigue adelante, crea
la liga, obtiene la identificación, crea el equipo, y luego solo te
deja saber que
todo está hecho. Entonces, si echabas un
vistazo a ese objeto de equipo, verías todos los datos
relacionados con el equipo y la liga. Entonces, cuando
volvamos, empezaremos a buscar hacer algunas consultas selectas
porque hasta ahora, solo
hemos estado poniendo datos, poniendo datos,
poniendo datos. Ahora, veamos cómo
podemos leer los datos de
la base de datos y mostrarlos
en nuestra aplicación. Bien.
12. Operaciones sencillas de selección: Chicos en esta lección,
vamos a estar
hablando de operaciones simples de selección. Ahora, antes de seguir adelante, solo
quiero
señalar que hicimos bastante desde las cosas
simples de inserción, y las he extraído
en métodos individuales. Entonces me he deshecho del código, y como que
los he comentado para que cuando
lo mires atrás, veas lo que está
pasando donde. ¿Todo bien? Entonces solo los tengo
comentados porque no queremos seguir agregando y agregando y
agregando los mismos datos antiguos. Entonces ahora es el momento de que
veamos la selección, así que solo voy a
separarlos, ponerlos a un lado, y luego podremos seguir trabajando en torno a
ellos. Todo bien. Entonces cuando hablamos de seleccionar, esta sería la R en CRD Entonces no sé si uso ese acrónimo antes de
hablar sobre este tema, pero CRD crear leer
actualizar eliminar, ¿verdad Ese es un acrónimo que es ampliamente utilizado en el desarrollo de
bases de datos, y representa básicamente
las cuatro operaciones que siempre
realizarás en una
base de datos en cualquier aplicación. Estás creando datos,
que es lo que acabamos cuando
miramos a insertar, eso es crear
vas a leer datos,
es
decir, quieres
recuperar los datos que están en la base de datos. Eso es lo que vamos a hacer ahora, y luego luego
veremos la U y la D, que significan
actualización y eliminación. Ahora, cuando queremos recuperar
datos de nuestra base de datos, comenzamos a pensar en
formular lo que
llamamos consultas de enlace
o declaraciones de enlaces. Link, que es la abreviatura de consulta integrada en
lenguaje. Básicamente es un dialecto. Yo lo llamo dialecto de C agudo. Es una forma que te permite escribir una consulta usando C sharp, y luego por supuesto, FC
va a traducir eso a QL Empecemos. Lo primero y más simple que puedes hacer. La consulta de enlace más sencilla
para recuperar datos de la base de datos sería y sólo voy a
definir una variable. Entonces quiero que todas las
ligas vuelvan, y voy a decir que Regus
es igual al contexto,
que es conexión a que es conexión a la tabla de base de datos que me
interesa, que es ligas Y esto le está diciendo esa mirada en el conjunto de ligas
DB. Pero entonces lo quiero en una lista. Entonces voy a decir punto a lista. Entonces me va a pedir que
incluya cierta biblioteca. Yo solo voy a controlar ¿ves que me está
diciendo que
necesito el
link punto del sistema de bibliotecas para poder hacer esto? Yo sólo voy a seguir
adelante e incluir eso, ese error desaparece. Y así así, ya lo
he dicho, selecciona estrella de la
tabla llamada Ligas. Eso es más o menos. ¿Verdad? Entonces lo que va
a pasar es que el contexto crea conexión con
la base de datos. Va a la
tabla de la liga y luego esta lista dice,
extraer los datos, traerlos de vuelta en forma de tula, pero luego materializarlos en
una lista de objetos de liga Justo de la misma manera que habíamos
creado la lista de equipos, dónde está, aquí está
mi lista de equipos. la misma manera que creamos
la lista de equipos, es de la misma manera que se va a materializar en la
lista de ligas para nosotros. Entonces lo que voy a
hacer es hacer una por cada uno, y voy a decir por
cada liga en ligas. Quiero consola
punto línea derecha. Así que solo estoy guion
usando un guión para separar el ID del nombre Todo bien. Entonces echemos
un vistazo a eso. Todo bien. Y cuando miramos la salida, vemos aquí la sentencia
que se ejecutó, seleccionamos ID y nombre de
ligas como L, ¿verdad? Entonces eso es básicamente
esa sentencia SQL, que solo podrías
copiar desde la consola, pasar a tu
estudio de administración y ejecutarla. Así que eso es muy útil cuando estás
resolución de problemas, tal vez escribiste una
consulta y
no estás recuperando los
resultados que deseas. Siempre puedes obtener
esa sentencia SQL e intentar descifrar por qué este
cle está siendo malformado Una vez más, esa es una herramienta
muy poderosa. No obstante, cuando echamos un
vistazo a los objetos
que se están imprimiendo, vemos todo lo que
hay en la base de datos. Entonces mientras probábamos, probablemente entramos a la
Premier League con correa de tierra algunas, demasiadas veces, también a
la Premier League, pero luego vemos también todas las
demás ligas. Entonces eso es lo que
obtenemos cuando simplemente decimos contexto, nombre de
tabla,
dame como lista. Ahora bien, algunas cosas importantes a tener en cuenta cuando se trata
de la sintaxis, esto es lo que llamamos la sentencia
ejecutora. Entonces sin esto, esa
consulta no se ejecutaría. Esto solo diría, Bueno, legs es ahora solo el hash set o el DB puso fuera de la mesa
llamado legs, ¿verdad? Entonces cuando ponemos en la lista to, ahí es cuando realmente dice, iré y
ejecutaré
esa consulta y
las enumeraré y las
enviaré de vuelta como objetos Entonces, si se suponía que íbamos
a hacer algo como dejar fuera la lista
para luego seguir ejecutando esto. Esta consulta
no se ejecutaría hasta que realmente inicie
los cuatro cada bucle. Entonces simplemente sería como
en estado de estasis aquí. Y luego cuando empezamos a cuatro cada uno a través,
entonces diría,
Bien, bien, déjame ir a buscarlos para que pueda
enumerarlos a través Ahora bien, el peligro de
hacerlo de esta manera es que la conexión permanecerá abierta durante la duración
de estos cuatro cada bucle. Ahora bien, con sólo 15 discos, eso no parece
gran cosa. Quiero decir, bien, bien.
Pero entonces cuando estás pasando por
una base de datos más grande, tienes esa conexión abierta. Y pensemos en cada conexión a
la base
de datos como una
operación costosa en cualquier sistema, ¿verdad? Entonces quieres reducir
eso tanto como sea posible. Y tampoco
quieres que una conexión esté abierta por mucho tiempo o
más tiempo de lo necesario. Entonces cuando hacemos la
declaración así e incluso podríamos
deshacernos de esas ligas parte de ella y solo decir para cada liga VR en
contexto ligas. El punto es que esto
en realidad crearía un candado y uno muy
ineficiente en eso De hecho,
cuantas más operaciones tengas haciendo en
eso para llegar a tu alcance, el tiempo entre
pasar por cada artículo aumenta,
y luego por supuesto, la conexión permanece abierta, y se vuelve aún
más cara. Entonces solo lo estoy
señalando, sí, podrías probar esto y funciona, pero no es la forma más
eficiente de hacerlo. La forma más eficiente y la forma más inteligente de
hacer esto, una vez más, sería poner en esa operación de
ejecución, dejarla iterar
y obtener la lista,
y entonces esa lista no se almacena en Esa conexión no está
cerca de la base de datos, y luego puede hacer todas
sus operaciones y manipulaciones contra los
datos después. Todo bien. Entonces eso es realmente todo por hacer
las simples consultas de selección. He extraído todo ese código y
lo puse en este método, que es un método de vacío estático. Entonces esta no usa ninguna operación
asíncrona. Entonces no necesitamos que
sea una tarea asincrónica, ¿verdad? Entonces es un simple vacío. Y lo que he hecho
es destacar cuál es bueno y
cuál es más o menos malo. Entonces no todo lo que
funciona, aunque
funcione, tiene algunas
ramificaciones subyacentes de las que quizás no estés consciente, pero por eso estoy aquí para
señalar cuál es la mejor manera de
engullir tus operaciones. Bien.
13. Filtering Records: Oigan, chicos, bienvenidos de
nuevo en esta lección, empezaremos a ver cómo
podemos filtrar nuestras consultas. Ahora bien, el estudio de caso para
filtrar es obvio, ¿verdad? Lo que hemos visto en
la selección simple es que estamos seleccionando todos y luego estamos
iterando a través de todos Hay
situaciones en las que no quieres todo, quieres registros específicos, y eso es lo que vamos a
estar viendo primero. Así que he creado un
método de consulta de filtros. Y antes de seguir adelante, quiero destacar que
sí dije que hicimos este vacío porque no estaba pasando nada sincrónico
en este método. Bueno, gracias a la entidad
Framework Core, sí
tenemos que listar A sync. Y cuando controlo eso, solo
tengo que agregar eso usando sentencia para entidad
Framework Core. Y luego gracias a eso, ahora
puedo hacer esto sincrónico. Así como agregar el peso
antes de la llamada AC. Así que pasemos a
nuestros filtros de consulta. Entonces cuando queremos
agregar un filtro de consulta, y voy a decir ligas
es igual o contexto,
punto, la tabla que nos
interesa, que es ligas, luego punto, y tengo acceso a una serie de métodos de este
lado. Entonces si quisiera decir, dame todas las ligas donde
el nombre es igual a algún valor, entonces puedo decir punto, donde y luego esta función
donde toma un parámetro que
parece un predicado
o es un predicado o una expresión Lambda Entonces el formato para una expresión Lambda es
que tienes algún token. Voy a
llamarlo P. La mayoría de los ejemplos en Internet, los
verás usan Q. Sin embargo, no hay estipulación cuanto a lo que debe ser este token Por supuesto, lo tratas
como un nombre de variable. Entonces, si quieres usar Q, si quieres usar liga, ya
sabes, sea lo que sea. Entonces si dije Q y luego le sigue
esta flecha Lambda, entonces ahora puedo usar Q para representar cualquier
registro en la tabla. Entonces ese es el formato
de la expresión Lambda. Si usé x's lo mismo. Si escribí la
palabra liga
solo estoy resaltando
que realmente no
importa cómo la llames, todas funcionarán de la
misma manera. A lo mejor éste se leería mejor porque una vez más,
se trata de decir base de datos, dame la tabla call ligas y dame los registros donde cualquier liga tenga un nombre que sea equivalente
a algún valor. Si quisiéramos encontrar decir Siri, entonces así
sería eso Una vez más, este token
podría haber sido Q, podría haber sido x, podría haber sido y,
podría haber sido Z. Así que realmente no importa
lo que uses como ese token Ahora bien, si hago esto, no
se ejecutará hasta que, una vez más, terminemos
con nuestro a listar. Ya que tenemos la
versión A sync de la lista to, podemos decir a listar A sync, y luego voy a
esperar eso y por supuesto, hacer del método una tarea de sincronización A. Entonces después de hacer todo eso, voy a repetir esta operación donde solo
voy a imprimirlos todos en la consola. Espero esta función
llamada y claro, y espero va antes que
todo lo demás. Sólo voy a arreglar estas
cosas antes de seguir adelante. Entonces cuando llamamos a eso, va a seguir adelante miren en la tabla donde se cumpla esa
condición. Entonces esto va a
ser verdadero o falso, así que o bien está cumpliendo
la condición o no. Si ha cumplido con la condición, se agregará a la lista y eventualmente se devolverá aquí. Así que vamos a ejecutar esta consulta
y ver qué obtenemos, ¿verdad? Y luego vemos que
está regresando. Tenemos nuestro único
registro regresando. Si echamos un
vistazo al pozo SQ, vemos que es solo una
simple consulta de selección, pero agrega sobre esa cláusula fueron con esa condición. Todo bien. Ahora, codificé duro. Observe que a diferencia de
las otras veces cuando vio los parámetros, en realidad solo puso el valor real
dentro de la consulta, y eso es porque
estaba un poco codificado. Por lo que sí mencioné que la
parametrización es una buena protección
contra la inyección de CQL Entonces, la razón por la que FCR no ha utilizado parametrización en
esta situación es que ve que yo soy
quien codificó duro el
valor del código Así que no pondría una inyección SQL directamente
en mi propio código. Entonces claro, como, bien, es seguro porque mi amo
es quien hizo esto, entonces debe estar bien, ¿verdad? Pero entonces la realidad es
que en situaciones normales, probablemente
estarías obteniendo
lo que sea que estés buscando de otra
parte, ¿verdad? Así que pongámonos un
poco creativos aquí. Entonces voy a ajustar un poco
esta función, y voy a decir consola ese nombre
interliga de la línea derecha Entonces esta vez estoy incitando
al usuario. Entonces una vez más, esta
es una aplicación de consola pero en una
aplicación web o así sucesivamente. Por lo general, permites que el usuario represente o determine qué
es lo que necesita, ¿verdad Y se lleva a cabo el
filtrado en consecuencia. Entonces estoy incitando al usuario, y luego vamos a almacenar la respuesta en esta variable Y entonces esa es la
variable que voy a usar para ejecutar la consulta. Entonces voy a decir donde
La expresión Lambda, nombre de punto
Q es equivalente
a nombre de liga. ¿Todo bien? También podríamos
decir punto igual, porque podríamos simplemente confiar en las funciones C sharp que probablemente usaríamos
en una declaración regular, pero notas que eso se
parece a una declaración, ¿verdad? Es el mismo tipo
de operador lógico que usarías
en una condición. Porque una vez más, esta es solo una condición que
necesita ser verdadera o
bien, necesita ser cierta
para poder ser incluida en la lista. ¿Correcto? Entonces ahora
como que nos jactamos de ello. Ahora podemos interactuar un poco más
con él. Entonces voy a ejecutar esto, y vamos a
ver las indicaciones. Ya entré en
Siria Presiono Enter. Y luego tardaron 83 milisegundos salir y mirarlo, ahora parametrizó
nombre Y luego se está ejecutando
con el parámetro. Así que ya ves, una vez más,
esto es automáticamente una especie de salvaguardia contra inyección de
CQL a través de
la parametrización,
estamos recuperando estamos recuperando Ahora, solo tenemos una
liga con ese nombre, pero sí teníamos múltiples ligas premier de raya
roja. Entonces voy a intentar esto de
nuevo con algo que sé que va a
devolver múltiples registros. Estamos intentando de nuevo con la Premier League de rayas
rojas, y el filtrado ahora
traerá de vuelta todos los récords. Ya ves que está funcionando. Es traer de vuelta a
cada uno que tenga ese nombre exacto. Y recuerda que esta vez
no usamos el
doble signo igual. Usamos el C sharp
porque esto es una cadena, así que dijimos punto
es igual a nombre de liga. Entonces nos permite escribir
esa sintaxis C sharp con la que
estamos familiarizados
en otras partes de nuestro código directamente en la consulta, y simplemente maneja todo
el resto por nosotros. Ahora, hagamos un experimento
más aquí. Hay
situaciones en las que su filtro podría no ser tan exacto como
un verdadero o falso. Podría ser una especie de lógica
difusa donde quieras
saber si contiene, especialmente cuando estamos
tratando con palabras, ¿verdad Entonces, en una búsqueda típica, podrías
escribir una parte de la palabra o parte de la
expresión que estás buscando, y luego
verías resultados coincidentes. Entonces he extendido el prompt para decir
nombre interliga o parte de, y entonces lo que vamos
a hacer es hacer dos consultas Entonces voy a tomar todo
esto y
duplicarlo Y lo que voy a hacer es llamar una coincidencia exacta y la otra coincidencias
parciales. Entonces para los partidos parciales, no
voy a decir punto igual, pero voy a
decir que el punto contiene. Porque en C sharp, si tuviéramos que tratar de
averiguar si una cadena tiene otra cadena en
ella para decir punto contiene. Entonces eso es lo que voy a pasar por alto en esto
eran expresión. Entonces echemos un vistazo a esto. Así que sólo voy a
usar voy a introducir un poco de cadena para buscar. Voy a entrar
premier ¿verdad? Sé que no tengo ninguna liga que sea un
partido exacto para premier. Entonces ya vimos funcionar los partidos
exactos. Pero sólo voy
a escribir estreno. Y entonces lo que vas a notar es que va
a ejecutar ambas consultas. Entonces va a
decir, ejecutó
esto, está buscando premier. Entonces este tiene la cláusula de desgaste para el nombre de liga premier.
Por supuesto, no hay. Pero entonces éste
tiene el nombre de liga como o índice de gráfico L
nombre punto es mayor que cero. Así que simplemente traza
toda una consulta agradable para decir, estoy buscando algo así como lo que hay en el
parámetro. ¿Todo bien? Y entonces es cuando vemos
volver a
todas nuestras ligas que tienen la palabra premier. Todo bien. Entonces esa es otra forma en la que
puedes ir filtrando
tus consultas. Ahora, cuando se trata de la,
puedes usar el contenido, lo siento, o puedes
usar funciones EF. Así que solo voy
a duplicar esto, y voy a encomiar esa parte, así que esa es la opción uno Otra opción sería
utilizar la función. Así que todavía necesito el token, todavía necesito inicializar esto, pero voy a
decir funciones EF Punto. Y entonces ves aquí, puedo hacer contiene, puedo hacer y un montón de
otras funciones que
estarían disponibles para mí si
estuviera haciendo SQL directo. Algunos de ellos están
aquí para acceder para nosotros. Entonces voy a hacer algo así porque eso se
parece más a lo que estamos buscando. Voy a decir como y luego voy a
decir q nombre de punto. Entonces el método toma, ¿cuál es la expresión
o cuál es la cadena? Cuál es la columna de base de datos en la
que estoy comparando. Y entonces el segundo parámetro sería el patrón de cadena. Si quería poner en
un patrón específico, si estás familiarizado
con la coloridad entonces
sabes que cuando
estás tratando con como, tienes ese comodín Entonces podría decir módulo premier, lo que significa que comienza
con la palabra premiere. Si ponemos el módulo al frente, termina con la palabra premier. Entonces, lo que sea que
hayas hecho en SQL para
ese módulo para ese bit comodín, puedes hacerlo dentro
de la cadena y simplemente lo
agregará y creará esa expresión exactamente
como lo que esperaríamos. Entonces en nuestra situación, porque estamos tratando
con esta variable, tengo que ponerme un poco más elegante. No quiero codificar duro
lo que estamos buscando. Yo solo voy a usar
alguna interpolación aquí, y solo voy a poner en el valor que viene
de la entrada Entonces estamos diciendo, consígueme
todas las ligas donde El nombre es como este patrón de
búsqueda. Todo bien. Entonces déjame hacerlo una
vez más para que podamos ver qué va a escupir
eso Esta vez, voy
a teclear La. No lo sé.
No tengo Liga. No sé qué
otra liga la base de datos podría tener
las letras LA en ella, pero vemos que la Liga
está siendo devuelta. Y si volvemos a mirar esa
consulta, vemos que nos está dando el formato y luego está
diciendo donde está el nombre como. Ese parámetro. Entonces ves
ese tipo de aspecto un poco más
limpio que lo que generó la consulta
contiene, pero al final del día, ambos nos van a
dar resultados muy similares, si no los mismos. Entonces eso es todo por un
pequeño experimento con el filtrado de nuestras consultas. Cuando volvamos, veremos cómo
podemos ir sobre la agregación de
datos, tal vez uno, el primero y la lista,
el último y la lista, nosotros uno la suma de todo en la lista, ese tipo de cosas Así que cuando volvamos,
vamos a echar un vistazo a eso.
14. Métodos de ejecución adicionales: Oigan, chicos, bienvenidos de nuevo.
Entonces, el objetivo de esta lección es
comprender o apreciar algunos de los otros métodos que
tenemos disponibles a través de Lincoln FCR y
cómo funcionan exactamente Entonces ya he seguido adelante
y creé un nuevo método, y esto es para métodos de
ejecución adicionales. Entonces tengo una declaración aquí que se parece a
una declaración select proveniente de nuestras actividades
anteriores donde tenemos contexto
que lleva a donde, y solo digo que contiene A. Ahora, el estudio de caso para una función
agregada o uno de estos métodos de
ejecución adicionales
sería que probablemente no
quieras la lista completa. Probablemente quieres que
se haga algo contra la lista o
quieres elegir la lista? Entonces cuando hablamos de funciones
agregadas en C, hablamos de cosas
como Min max,
count, algunas, ese
tipo de operaciones, todas esas están disponibles para nosotros a
través de estas funciones
agregadas adicionales. Ahora bien, otra cosa que probablemente
querrías
hacer es obtener el primero o
el último de una lista, ese tipo de cosas, ¿verdad? Entonces solo voy a usar
esto como un ejemplo rápido. Y ¿y si quisiera la primera liga que
tiene la letra A en su nombre? Entonces después de ver toda esta afirmación y
agregar el filtro, entonces la
terminaría con
una primera o por defecto. Verás aquí que
tenemos, por supuesto, los métodos Async y por cada AC hay
una versión no AC Pero no es necesariamente
al revés. Entonces no todos los métodos tienen
una contraparte Async, pero lo verás más adelante Bien. Entonces aquí, puedo decir que quiero un primero o por defecto o
puedo decir el primero. La diferencia entre
first y first o default es que primero siempre
esperaremos
ver una lista y
obtendrá la primera. Entonces, si no se devuelve nada, entonces lanzará una excepción. Se terminará la ejecución
con un error. ¿Todo bien? Primero o default over dirá, voy a intentar obtener el primero y si no hay nada que conseguir, entonces voy a devolver null sin terminar la
ejecución en ese punto. Bien, entonces primero o por defecto
es probablemente un poco más seguro. Y entonces lo que eso
hará es simplemente recuperar la única liga que está
en la parte superior de la lista. Todo bien. Ahora bien, en realidad
podríamos simplificar esto porque
lo que estamos haciendo aquí es decir dame
la cláusula de trabajo y luego ponerle la condición
y luego conseguirme el primero. En realidad podría haber
hecho esto. Yo podría haber dicho contexto hacer ligas hacen primer
defecto estrella, esta condición. Ese es un método de ejecución. Recuerda ir todo el camino de
regreso a nuestro sencillo selecto. Sing context dot leg realmente
no hace nada, pero luego una vez que ponemos
ese método, se ejecuta Vimos lo mismo con
la lista y la vajilla. Pero en esta situación, solo
puedo decir primero estrella default y luego esa condición
y luego
ejecutará la consulta en consecuencia. Así que solo voy a romper
y mostrarte algunos otros métodos de ejecución de
uso común. Entonces voy a
reemplazar esa línea con una simple declaración que está obteniendo nuestro DB establecido aquí, ¿verdad? Y claro, desde
que tenemos el conjunto DB, podemos acceder de los métodos de
ejecución. Así que vamos a ir a través de
ellos tipo de orden. Entonces ya
miramos al tost. Sabemos que los
peajes van a ejecutar el comunicado Selcti También tenemos primero
y primer R por defecto, y acabamos de discutir la diferencia entre
los dos, así podemos decir que las fugas puntean primero una sincronización o primero R por defecto
una sincronización y una vez más, sí
tienen
versiones no asíncronas a estos métodos Según tu situación, es posible que estés usando la sincronización A, es posible
que no estés usando la sincronización A, pero solo la mantendré consistente y permaneceré
con la sincronización A. También tenemos el default simple
o único. Soltero hace lo que haría
el primero excepto
primero es ver una lista, y solo va
a escoger el primero, literalmente primero de la lista. Single va a operar
similar al primero donde si está buscando uno, primero está esperando una lista y va a
tomar el primero. Si no se devuelve ninguna lista, entonces esto arroja un error. Single espera que
solo se devuelva un registro. Entonces, sea cual sea lo que esté esperando que solo se devuelva un
registro. Si ve más de uno, también lanzará una excepción. Single simplemente no lanzará la excepción sino que devolverá default en
circunstancias similares. Siempre puedes leer
más cuando solo pasas cursor sobre el método, te dará algo de
educación en cuanto a lo que hace Ahora bien, cuando se trata de algunas de las
funciones agregadas tradicionales que probablemente
sabríamos de
SQL, ves contar. Entonces puedes decir ligas punto count sink ejecutarás
la consulta de conteo. Tienes conteo largo,
tienes mínimo, tienes máximo, tienes S, tienes un número de otros. Como dije,
siempre puedes decir ligas punto o contexto punto de tabla de puntos, y luego puedes
desplazarte y verás la plétora de métodos
disponibles para Puedes elegir usarlos
cuando necesites usarlos. Pero sentarse y tratar
de pasar por todos
ellos a la vez puede
ser agotador, pero en cualquier momento crees que
tienes una idea en mente Siempre puedes simplemente hacer el
espacio de control de puntos y simplemente mirar a través y ver cuál de estas carnes necesitas en ese
momento. Ahora bien, otro método de ejecución, que no es necesariamente un método de consulta
como uno de estos, sino que se ejecutará contra
un conjunto de bases de datos es encontrar una sincronización. Este en realidad solo
saldrá y buscará en base a un valor, entonces ese valor va a
ser el valor clave, ¿verdad? Entonces encuentra una entidad con
una clave primaria dada. Entonces, cuando dices encontrar una sincronización, se espera
que pongas identificador
único que
sea, por lo tanto, esa tabla, y luego traerá de
vuelta ese registro. O lo traerá de vuelta
o traerá de vuelta nulo, ¿verdad? O devolverá el
registro o devolverá nulo. Entonces así es como ese
encontrar un trabajo de sincronización. Entonces intentemos ejecutar y veamos exactamente cómo nos
funcionaría esto. Así que he establecido un punto de quiebre
al inicio de este método, y sólo voy a
pasar paso a paso que podamos ver el C
quel que se está generando. Creo que cuando llegue
al single y
single o default o al
menos al primero, probablemente arroje un
error en uno de estos, pero pasemos adelante y veamos exactamente
qué está pasando. Entonces he puesto mis ventanas una
al lado de la otra para que
podamos ver cada paso del camino. Entonces cuando decimos a listar, seguiremos adelante y
ejecutaremos esa, y luego vemos aquí
que estamos consiguiendo
esa consulta de selección con la que ya estamos
familiarizados. Entonces voy a ir
a hacer la primera. Entonces ya ves que está
obteniendo el primero, es seleccionar uno superior. De liga. Todo bien. Entonces eso es lo que hace el primero. Y el primero o por defecto, si no me equivoco, generamos prácticamente
el mismo SQL que el primero. Pero como dije, si primero
no ve nada, entonces lanzará una excepción. Ahora, el single definitivamente
va a lanzar una excepción porque solo está
esperando un disco, pero es conseguir la lista
y decir uno sencillo. Entonces cuando pisamos con esa, entonces arroja esa
excepción. Ahí vamos. Entonces la excepción es que secuencia contiene
más de un elemento porque esperaba que solo
se devolviera un elemento, ¿verdad? Entonces solo voy a
matar esa ejecución, y voy a
comentar esa línea solo para que
podamos continuar con el
resto de la ejecución. Entonces continué la ejecución contra todos los demás métodos, y verás a la derecha, algunos de ellos
tuvieron éxito, otros no lo fueron. Así que solo singular default y prácticamente todos estos
matemáticos los a través de errores, Realmente, porque, bueno,
realmente no estoy haciendo nada
matemático aquí. Tengo que asegurarme de que estoy encontrando la
media de algo, encontrando el máximo de algo. Obviamente, eso no
está pasando realmente cuando solo
digo ligas, ¿verdad? Pero el punto es que estos
son algunos métodos adicionales que puedes usar
cuando estás haciendo tus operaciones más complejas. Y si miras a la derecha, verás eso
hasta la cuna cuando
preguntamos cuando pedimos contar y
pedimos un cont largo, la diferencia entre
los dos era que teníamos select cont star para
la cuna y luego seleccionar cont big star
para el La única diferencia material
realmente es que count devuelve un entero y éste
devuelve un entero grande. Entonces, ya sabes, basado en
el tamaño de la base de datos, posible
que nunca termines usando conteo
largo o grande en SQL, pero el método está
ahí independientemente. Entonces eso es realmente todo para
los métodos de ejecución. A medida que avanzamos, podríamos
encontrar uso para ellos. Y tal vez necesitemos interactuar
con ellos de otra manera. Pero ahora mismo, no lo hacemos. Voy a comentar todos aquellos que
probablemente dieron errores, y solo quiero que veamos
la q que se genera
cuando tratamos de encontrar. Entonces vemos aquí la
ejecución para el hallazgo es que encuentra uno superior
donde se cumpla esa condición. Entonces todo eso una vez más
se genera para nosotros. Y lo más probable es que no
vamos a codificar
duro ese ID de todos modos, ese ID vendría
de alguna parte, ya sabes, como cuando alguien hace clic en
editar en tu interfaz de usuario. Hay que saber qué
registro pretenden editar. Tienes que ir a
buscar ese registro, devolverlo, y luego
presentarlo al usuario. Entonces ese es un estudio de caso para
cuando usarías ese hallazgo. Entonces eso es todo para nosotros mirando métodos de
ejecución adicionales. Como viste, hay
una lista mucho más larga que hemos
pasado por aquí. Pero tienes estas
cuatro referencias, y estoy seguro que encontrarás un buen
uso para ellas en el futuro.
15. Sintax, LINQ alternativo: Oigan, chicos, bienvenidos de
nuevo. En esta lección, vamos a estar
viendo la sintaxis de enlaces alternativos. Entonces, hasta ahora, hemos estado viendo
link en forma de
estos métodos de ejecución y diferentes
expresiones Lambda que
podemos colocar en algunas de
ellas para obtener nuestras operaciones
únicas a nuestras necesidades. Ahora, Eso está bien, usar el
método de expresión Lambda está perfectamente bien, y como puedes ver,
se puede escribir en una línea, agradable y limpia. Sin embargo, existe una sintaxis
alternativa que algunos desarrolladores
pueden encontrar un poco más intuitiva porque se ve un poco más similar a SQL
tradicional, pero sigue siendo C sharp. Entonces, esta es en realidad
la primera forma que solía
escribir un enlace antes de
descubrir o me sentí
lo suficientemente cómoda con las expresiones Lambda. Y tengo el código
preparado aquí para ti, así que sólo voy a
guiarte a través de él. Entonces, esta vez estamos
mirando a los equipos, ¿no? Y entonces nuestra sintaxis aquí
está diciendo de algún token. Entonces esto podría ser, ya sabes, usamos Q en nuestras expresiones
Lambda. Esto representa
algo así como eso P. Podríamos decir equipo, podríamos decir P. Estoy diciendo yo. Bien. Entonces de yo en, y luego decimos la mesa que nos
interesa buscar. Entonces contexto que
los equipos, luego seleccionen. Entonces, como dije, se parece un
poco más a Q porque en realidad tiene algunas de esas palabras clave
SQL, ¿verdad? Es solo un poco
hacia atrás porque habría sido estrella seleccionada de la mesa. Y éste es de
registro en tabla, seleccionar registro, o podríamos decir
seleccionar algo específico. Pero veremos eso más adelante. Entonces cuando haga esta consulta, me
va a dar
queriable de equipos, ¿no? Entonces eso significa que necesito
convertir eso en una lista. Pero ejecutemos
y veamos qué obtenemos, y luego podremos refinar a
medida que avanzamos. Si miras eso, en realidad ejecutó esta consulta
bastante perfectamente, ¿verdad? Nos dio nuestra selecta declaración, y nos está
devolviendo a nuestros equipos. Entonces no tuvimos que
decir explícitamente a la lista e
intentar convertirla. Ahora bien, uno de los beneficios, sin embargo, de tenerlo como lista, es que cuando está en
forma de quarable, nuestra capacidad de manipularlo hasta cierto punto
es limitada, ¿verdad? Entonces, si miré equipos, hay ciertas funciones aquí
hay ciertas funciones que son únicas para
i quarable y hay ciertas funciones
que son únicas para listas que probablemente
querrás usar más adelante en tu codificación que realmente no
puedes obtener cuando estás tratando
con una i quarable Entonces de vez en cuando, realidad solo envuelvo
todo esto en realidad solo envuelvo
todo esto entre paréntesis
y luego digo a la lista, y luego eso solo me
devuelve mi lista, que es un poco más nativa
de lo que me gustaría estar haciendo en mi código C sharp
al final del día Por supuesto, para hacer eso,
tengo que cambiar mi método de void a tarea AC, ¿verdad? Entonces entonces estamos obteniendo nuestra lista, y como pueden ver, la lista,
los tipos de colección funcionan, manera
bastante similar,
pero como dije, hay ciertas cosas
que la lista
nos brinda que una enumerable consultable, y el otro tipo de colecciones de
listas o tipos de colección en C
sharp, simplemente no lo hacen Pero claro, la
situación de todos es diferente. Usa el que sea
apropiado a tu contexto. Ahora, extendamos esto. También miramos a preguntar
, o lo siento. También nos fijamos en
filtrar nuestras consultas. Entonces en este momento, esto es solo
hacer una estrella selecta estándar. ¿Correcto? Pero, ¿y si
quisiéramos cláusula consciente? Bueno, diríamos
desde yo en mesa, y aquí sólo voy a
romper la línea. Entonces se ve un poco más legible. Dónde, y
verás que resalta esas
palabras clave para nosotros. Entonces donde yo que representa expresión o cualquier
registro en la base de datos. Entonces puedo decir donde
nombre es equivalente, y luego poner en mis registros. Entonces de la misma manera
que pudimos inyectar en o, ya sabes, una variable o un nombre estático
o cualquiera de esas cosas, podemos hacer todo
eso aquí mismo. Déjame ver si esto
funcionaría. Voy a tratar de decir, donde nombro o déjame decir
donde funciona EF como. Y entonces esto
sería yo no nombro. Y luego tenemos
el nombre de la liga, que solo voy a hacer un rápido incitando este
método para también, este sería el nombre del equipo Así que ingresa el nombre del equipo. Déjame cambiar el
nombre del verbo. Y ahí vamos. Entonces estamos solicitando el nombre del
equipo y parte de. Y entonces estamos diciendo
desde la mesa del equipo donde el punto funciona
como el nombre del punto, ¿verdad? Nuestra expresión, y
luego queremos seleccionar, y luego queremos poner
todo eso en una lista para
volver a nuestros equipos de llamadas
variables. Entonces esto va a
funcionar, claro. Solo estoy resaltando
el hecho de que podemos usar la sintaxis alternativa de la misma manera que
usamos nuestra expresión Lambda. Entonces aquí lo estoy probando
, y estoy escribiendo
B A Y como parte del nombre del equipo. Vemos nuestra declaración select con la declaración que se está
generando para nosotros, y estamos recuperando
Bar y Municx ya que es el único equipo que
tenemos que tiene BAY en Entonces, una vez más, esta es
nuestra sintaxis alternativa. Cualquier cosa que puedas hacer en
la expresión Lambda, también
puedes hacerlo en
este tipo de sintaxis. Personalmente, sin embargo, me parece
que las expresiones
Lambda son un poco más fáciles. Así que desde que me sentí
cómodo con ellos, en realidad
abandoné escribir mis consultas así. No he escrito
consultas como esta en años para ser honesto, pero es bueno tener
el conocimiento
de todas tus opciones
y alternativas, si es necesario. Bien.
16. Consulta sencilla de actualización: Oigan, chicos, bienvenidos de
nuevo en esta lección, vamos a ver
realizar una operación de actualización. Ahora, el
flujo de trabajo general para una actualización sería que
recuperes el registro, que pretendas modificar, luego hagas la modificación, y luego guardes los cambios. Entonces ese es un flujo de trabajo típico. En cualquier aplicación que utilices, eso es lo que está sucediendo
detrás de escena. Indicas que
quieres grabar el editor, va y encuentra ese registro, te lo
presenta, lo haces cambios,
y luego al
hacer clic en Guardar, bien, habrías realizado
los cambios de registro y luego el guardado comprometería esos
cambios a la base de datos. Todo bien. Entonces, primero veamos la recuperación de los registros Entonces, ¿y si quisiéramos modificar? Y tenemos algunos déjame
ir y mirar nuestras ligas. Tenemos algunos
valores duplicados aquí. Creo que tenemos tres récords de liga
de fútbol de raya roja. Y sí, lo hacemos. Entonces tenemos identificaciones, dos, tres y cuatro
siendo lo mismo. Entonces lo que voy a
hacer es simplemente cambiar los nombres en algunos
de estos, ¿verdad? Entonces voy a cambiar
el nombre de tres. Es un duplicado pero luego en
retrospectiva, nos damos cuenta, oh, que realmente debería haber sido la
premiership escocesa, Entonces sabemos que queremos
modificar registro con ID tres. Entonces lo que voy
a hacer para recuperar el registro es Liga SVR, z igual al contexto, las ligas sí encuentran, y solo
usaré una sincronización Por supuesto, si estoy usando una sincronización, tengo que transformar mi
método en una tarea de sincronización A, y luego la espero aquí. Entonces vamos a
decir, encontrar una sincronización, y luego recordar
que todo lo que tenemos que
pasar es la clave primaria, así sabemos que queremos
grabar con ID tres. Ahora, cuando lleguemos a esa liga, el cambio que quiero
hacer es el nombre del punto de liga, quiero que ese nombre
sea ahora el estreno escocés. Entonces guardamos nuestros cambios. Entonces ya miramos los cambios de
guardar desde cuando estamos insertando los mismos cambios de guardado. Cada vez que vas a
aumentar los datos en la base de datos, tienes que llamar a esto
para cometer el comando Entonces quiero imprimir el resultado de esto o quiero imprimir de nuevo
a la pantalla este disco. Sólo voy a crear un
método llamado get record, que es específicamente solo
para ir a buscar este disco. Lo tengo definido arriba aquí, o sólo voy a decir Varg, ve a buscar el mismo disco Entonces después de los cambios de guardado, entonces habría cerrado la
conexión a la base de datos. Yo sólo voy a
esperar obtener registro, que es sólo va a ir a recuperar el registro y
luego volver a imprimirlo la pantalla solo para demostrar que el procedimiento de actualización
fue exitoso. Entonces, démosle una meta a esa. Entonces cuando ejecuto, vemos aquí que
está haciendo la selección, ahí es donde está
haciendo el hallazgo, así recupera el registro, y luego está llevando
a cabo esa actualización, por lo que conserva la clave primaria y el nuevo valor
para este registro Y entonces lleva a cabo
esa sentencia update, establece el nombre para que sea cualquier
valor en ese parámetro, donde el ID está en
ese parámetro, y luego sigue
adelante y se actualiza. Y entonces, claro,
nuestro registro get es simplemente volver a abrir
esa consulta de selección, eso es un selquy y
devolviéndonos ese registro. Todo bien. Entonces intentemos eso otra vez, y no voy
a cambiar nada. Voy a dejar
el mismo registro. Voy a hacer
el mismo cambio y todo va
a seguir igual. Y luego veamos
qué pasó. Esta vez, no tenemos
una declaración de actualización. Toma nota de eso, ¿verdad? No tenemos una declaración de
actualización porque nota que
sea cual sea el cambio que esté haciendo, realidad no
es un cambio. Ese es el valor en
la base de datos ya. Entonces no va
a molestarse en perder el tiempo para decir, Oh, necesito hacer un cambio. CEFCO está eligiendo inteligentemente no abrir una conexión a la base de datos y llevar a cabo un comando que se da cuenta de que no
necesita Ahora bien, lo que permite que ocurra este
tipo de cambio, es
decir, que FCR está viendo que
los datos que estamos presentando para ese campo son diferentes, entonces sabe
guardar los cambios Esto se llama rastreo, ¿verdad? Nos fijamos en el seguimiento y
no seguimientos más adelante. Pero solo como una vista previa rápida, siempre que sea que
estemos modificando objetos, FCR en realidad está rastreando en
la memoria qué objetos tiene si hay
algún cambio realizado en
ellos para que cuando
digamos guardar cambios, diga literalmente, Bien, puedo ver que aquí
se hizo un cambio, tengo que comprometer este cambio, etcétera, etcétera Entonces eso es lo que nos
permite hacer el seguimiento. Ahora bien, hay otras
cosas que son otras formas en las que podemos
llevar a cabo una actualización porque es posible que
una actualización nunca sea
tan sencilla como encontrar ese valor exacto
y simplemente cambiar una propiedad y luego
simplemente guardar los cambios. Muchas veces cuando las personas, especialmente tienen interfaces de usuario y están interactuando
con un formulario, cuando
les permitimos editar los datos, no
sabemos qué ha cambiado. Así que no podemos estar seguros,
saber eso, bien, sólo
vamos a actualizar nombre, y sólo vamos a
actualizar esto y aquello. No sabemos si tal vez
en la edición de un equipo, cambian la
liga y el nombre. No lo sabemos. Entonces para este otro ejemplo,
voy a usar equipo. Así que renombré nuestro método de registro de actualización a simple
Actualizar registro de liga Entonces está claro que
estamos tratando con la liga y
fue una simple actualización, y luego ahora tenemos registro de equipo de actualización
simple. Entonces echemos un
vistazo a la alternativa. Ahora bien, en el
caso de que alguien que utilice una interfaz web
hubiera enviado el formulario, eso significa que ya tenemos toda
la información sobre el registro que necesitamos en ese
momento, es
decir, no tenemos que ir
a buscarlo antes de la actualización
porque ya
lo encontramos antes de
mostrarlo al usuario. Ahora el usuario ha enviado, tenemos los nuevos datos. Todo bien. Entonces voy a simular esto creando un pozo completamente nuevo, un objeto de tipo equipo, ¿verdad? Y entonces lo que voy a hacer
es especificar una identificación esta vez. Entonces, hasta ahora,
realmente no hemos dado ningún ID a ninguno de nuestros objetos porque
esos son autoincrementantes. No obstante, lo que tenemos que darnos cuenta es que cuando
un ID está presente, por
supuesto va
a buscar a través las tablas de
la base de datos
el registro con ese ID. Entonces voy a ir
a la mesa del equipo. Y lo que voy a hacer es insertar
manualmente solo
para que podamos pasar por este equipo de actividades
que es local. Está en la
Tira Roja Premier League, pero la voy a meter con algunos errores ortográficos,
¿no? Es Tivoli Este es Tivoli, y voy a ponerlo con
el ID de liga equivocado, porque no está
en la liga ocho, y en base a los equipos
de la liga ocho, podemos suponer No es en Siria, así que
tenemos que hacer ese tipo
de actualización, ¿verdad? Entonces digamos que esto fue ingresado
erróneamente
por algún usuario, y luego otro usuario
capta ese error, y se están poniendo
a escribir ese error Por lo que se les
habría presentado el formulario y luego
pusieron las correcciones, y luego
presentaron el formulario. Entonces el objeto que
habrían enviado se vería algo así
donde el ID es siete, ese es el ID para
este equipo, sí. Y el nombre habiendo
sido corregido es Tivoli Gardens FC con una O en lugar de AW, esa es
una ortografía correcta Y entonces el ID de liga ahora
sería la liga
premier de Red Stripe, ¿verdad? Entonces usemos League ID dos. Vemos que tenemos otro
duplicado, pero eso está bien. Solo usemos
liga con ID dos. Entonces esta es la actualización que
este usuario está enviando. Ahora bien, ¿cómo conseguimos este nuevo
registro en la base de datos? Bueno, podemos decir contexto equipos de liga
punto. Estamos tratando con la actualización de puntos de
equipos. Entonces tenemos un método de actualización, que al igual que el
anuncio va a tomar un objeto del tipo de datos que corresponde con la tabla. Entonces tenemos nuestro objeto de equipo. Observo que no hay
asíncrono no hay una versión
asincrónica Tenemos el single y
tenemos la versión batch, y ya
miramos el rango de lotes significa que si tenemos un montón
de ellos para actualizar, acabamos de entregar la lista y se ocupará de
todos ellos por nosotros. Ahora mismo, solo estamos
viendo el sencillo. Y luego después de eso,
tenemos que llamar a nuestro contexto dot save changes. Y usaremos la
sincronización A para esa. Y claro,
tengo que hacer de esto una sincronización y luego se resuelven todos nuestros
problemas. Echemos un vistazo a lo que se hace cuando pasamos en
este tipo de actualizaciones. Verás que es un tipo de operación
similar. Nadie, no
vuelve a actualizarse porque ve el ID. Entonces sabe que hay
un equipo con ID siete, y luego seguirá adelante lo
encontrará automático bien, no tiene
que encontrarlo
porque la declaración de actualización dice cambio de identificación de liga, cambio de
nombre donde
el ID es equivalente al ID que vio
entrar en el registro. Entonces es hacer todo eso
automáticamente una vez que ese ID de
registro está ahí. Entonces una serie de vamos a pasar por
una serie de permutaciones. Si no especificamos esta identificación, ¿qué pasaría realmente? Y yo sólo voy a usar
otro equipo de futbol, vamos a Ciba United, y eso también está en esa raya
roja de la Premier League Entonces probemos ese
y anotemos la diferencia. Este no tenía identificación. Salimos la identificación, y se la tomó como una cola para hacer un inserto. Toma nota de eso. Entonces el comando update o la función update
decían eso, no
veo una clave
primaria sobre esto,
esto claramente aún no existe
en la base de datos, así que seguiré adelante e insertarlo. Ahora bien, no estoy promocionando esto como una alternativa
al inserto Me gustaría
mantenerlos muy separados. Si estoy insertando algo, utilizo la función add. Si estoy actualizando, utilizo
la función de actualización, o simplemente la hago un seguimiento en consecuencia, pero el seguimiento no
siempre es una opción como la que estamos viendo en
nuestras aplicaciones. Pero una cosa a tener en cuenta, si esa identificación no está presente, seguirá adelante y la agregará. Por eso siempre nos
aseguramos de incluir la información de identificación
en un formulario para que cuando se envíe
ese ID esté presente en el registro para que podamos llevar a cabo
adecuadamente esa actualización. Entonces ese es un punto muy
importante a tener en cuenta. Y un experimento más es poner una identificación
que no existe. Entonces, si ese valor de ID es
completamente incorrecto. Tengo diez, y sabemos
que sólo tenemos bien, no hay ocho equipos, derecho, o equipos con ID ocho. Entonces ID diez está completamente equivocado. Intentará hacer la actualización, pero luego está lanzando una
excepción sobre los cambios de guardado, diciendo que la
operación falló,
bueno, esperaba afectar al
menos a una fila,
pero afectó a cero. Podría haber habido
alguna modificación los datos que contienen. Entonces puedes ver aquí en
realidad no te está diciendo
exactamente lo que está mal. Sabemos que esto
es incorrecto porque el valor de ID no existe. Y está diciendo que pensó
que haría al
menos un cambio,
pero no pasó nada. Entonces no está muy seguro de
lo que pudo haber pasado. Tienes que ir y hacer algunas
lecturas sobre la documentación. Pero como dije, quiero ver qué puede causar
estos errores
para que cuando
nos den errores un poco vagos
como este, podamos suponer que, bien, debe
haber algo
mal con algunos de los datos que
proporcioné en algún lugar
de Entonces eso es realmente
todo para la actualización. Como puede ver, es una operación bastante
sencilla. Tienes dos opciones una vez más. Puedes ir a buscar el registro, hacerlo cambios, y
luego guardar los cambios, y luego rastrear
permitirá a COR saber que,
bien, este registro fue modificado, así que tengo que crear la declaración de
actualización para ello. Porque aunque tengamos una lista de ellos, si solo hicimos cambios a uno, sabrá
que solo hay que
actualizar uno, ¿verdad? Y la alternativa saber u otra situación podría ser donde seguimiento no es
necesariamente una opción. Y el registro que lleguemos a actualizar no está siendo rastreado
por FCR en ese momento, lo que podemos usar ese método de
actualización, que seguirá adelante y buscará el registro y generará la declaración de actualización
automáticamente Si no hay ID presente, entonces el método de actualización
continuará y agregará el
nuevo registro. Bien.
17. Eliminar consultas sencillas: Y estamos de vuelta. Entonces, hasta ahora, hemos mirado
todas las letras en CRD excepto la
D, que es eliminar Entonces hemos
mirado cómo crear. Pasamos un tiempo mirando cómo podemos recuperar y
las diferentes formas. Solo miramos cómo
actualizamos y ahora queremos
saber cómo eliminamos o eliminamos
datos de nuestra base de datos. Entonces ya
configuré dos métodos, uno para mostrar un ejemplo simple de
eliminar y luego otro donde mostramos una eliminación cuando hay datos
relacionados. ¿Todo bien? Entonces el simple eliminar. Echemos un vistazo a las opciones que tenemos disponibles. Y voy a pasar algún tiempo con la tabla de liga porque
tenemos que hacer alguna limpieza. Uno, tenemos duplicados
aquí y aquí. Y entonces probablemente también
queremos eliminar a la Bundesliga. Entonces eso es lo que vamos
a hacer hoy. Todo bien. Entonces cuando digo contexto
punto y elijo una tabla. Entonces en este caso,
es ligas punto, y luego empezar a escribir Eliminar, o más bien eliminar mi mal, veremos que
tenemos dos opciones. Hemos eliminado y
hemos eliminado rango. Así que elimine como agregar y actualizar acuerdos con
un registro a la vez, y luego las
operaciones de rango son para granel. ¿Todo bien? Entonces, cuando
digo quitar y solo echar un vistazo a lo que
requiere para hacer una remoción, veremos que necesita que se elimine a
toda la entidad. Todo bien. Así que normalmente cuando estás escribiendo
una sentencia q, dirías delete
from table we maybe ID is equal
to one. Todo bien. Y entonces solo irá por eso
ir por cualquier registro que
coincida con la condición me dieron y eliminar eso. Y sin esa condición, en realidad
solo limpiará la mesa. Entonces al menos, aquí hay una red de seguridad donde
tenemos que
proporcionar la entidad o la lista
de entidades a eliminar, lo que significa que tenemos que hacer un esfuerzo muy deliberado para saber que esto es lo que queremos
eliminar durante el tiempo de ejecución Por lo que el riesgo de borrar
la base de datos se ve muy reducido en esta
situación. Todo bien. Entonces, claro, si
necesitamos proporcionar a la entidad que
se va a eliminar. Y si solo
miras la documentación, dice
que el remove pone a la entidad en un estado
llamado eliminado. Entonces lo marca para que se elimine, pero como saben, no
pasa nada hasta que
llamemos guardar cambios. Entonces, si necesito proporcionar
una entidad a este registro, entonces claramente necesito ir a
buscar lo que necesito eliminar. Entonces voy a poner
en una línea justo arriba de esa donde estoy
encontrando la liguilla con el ID cuatro cuatro porque ese es uno de mis
duplicados, ¿verdad Y éste no tiene
ningún registro relacionado. Entonces esta es una simple eliminación. Apenas encontrando el que
tiene el ID cuatro, cuando lo consigamos, entonces podemos decir, ese es el que
quiero quitar. Y entonces como sabemos, decimos guardar cambios. Por supuesto, usando el
ASIC para agregar un s dos, la declaración del método,
Bien, y ahí vamos Entonces cuando llame a esa, y por ahora solo voy a
comentar esa segunda convocatoria. Cuando ejecuto esta operación, vemos donde se rasgó la consulta de selección para
recuperar el registro, y luego salió y dijo, eliminar de ligas la misma
consulta que conocemos y amamos Por supuesto, con esa cláusula
eran
asegurarnos de que no borremos
las tablas en la base de datos. Todo bien. Así es como funciona realmente una
simple eliminación. Ahora bien, la razón por la que estoy
diferenciando entre una simple eliminación y una eliminación con relaciones es que cuando tenemos registros
relacionados, una operación de eliminación se vuelve
un poco más sensible Es decir, bueno, hay una
configuración llamada eliminación en cascada, lo que significa que si elimino el registro
con una clave primaria, entonces todos los demás registros que tengan una clave externa para este también
serán eliminados. Bien, así que casi sería como eliminarte de una base de datos. Así que todas las tarjetas que alguna vez has
tenido y toda la
información
relacionada contigo también serán
borradas de varias partes
de la base de datos. Si bien eso podría ser bueno
en algunas situaciones que podrían ser muy peligrosas
en otras. Todo bien. Entonces en esta situación, si voy a ir a eliminar
Bundesliga con ID nueve, así que solo estoy repitiendo
todo el mismo código del símbolo eliminar Lo que hace la diferencia es
que sé que tengo al
menos un equipo
relacionado con la liga Bundes, ¿verdad Entonces eso significa que si
eliminé Bonds Liga, entonces ese equipo
también se eliminaría. la misma manera
si eliminaba a Siria, entonces uno, dos, tres
equipos serían removidos. Ahora, volviendo a nuestro archivo de migración solo para que
podamos entender las reglas de restricción cuando se creó
la tabla cuatro equipos y se puso la restricción de
clave externa, por defecto, dio acción
referencial hacer cascada Hay otras opciones
que podríamos establecer aquí. Por lo que podría decir restringir, decir, no se puede
llevar a cabo una eliminación en ningún registro que tenga registros relacionados
o dependientes. Establecer Nulo significa que
establecerá todos los demás registros,
todos los registros relacionados, el valor de la clave externa
ahora se convertirá en nulo, ¿verdad? Digamos que eliminaremos
el padre y simplemente estableceremos todos los valores de
clave externa en nulo. Y entonces no tienes acción, que es, bueno, dice, ignorar la restricción, y luego otra
que diga default,
que simplemente establecería un
valor por defecto después, ¿verdad? Entonces voy a dejarlo
en la cascada predeterminada, pero una vez más, esta podría no ser siempre la
mejor situación. Y hay momentos núcleo de framework de
entidad en
la generación de la migración
realmente te indicará que si pongo en cascada ahí, puede encontrarse ciertos tipos de errores
porque, ya sabes, esta tabla podría
tener una
dependencia de esto y
aquello y obtienes una referencia circular tipo de situación o tablas diferentes
confiando en los mismos datos. Por lo tanto, CO le avisará en situaciones en las que el diseño de su
base de datos puede no ser óptimo para este tipo de regla de restricción. Todo bien. Entonces con todo lo dicho, intentemos llevar a cabo
nuestra eliminación en la Bundesliga, que sabemos que tiene un
equipo relacionado y veamos qué pasa Entonces, cuando echamos un vistazo a
la qua que se genera. No se ve diferente de lo que vimos con
el anterior. Entonces probablemente te estés
preguntando, bien,
entonces, ¿dónde está la segunda eliminación
para el registro relacionado Verifiquemos que eso pasó. Entonces si refresco equipos, Bundesliga se ha ido,
perdón, ligas, y luego si refresco equipos, eso significa que Burn
Munich también se ha ido Entonces la cascada sí ocurrió, pero nuestros registros solo
muestran una eliminación. Eso es porque una regla de cascada está realmente en el ingeniero de
bases de datos. No es necesariamente
una declaración ca la que se
generará. Todo bien. Entonces esa
regla de migración estaba realmente establecida en la base de datos cuando
afectamos la migración. La propia base de datos
sabe que la regla es eliminar todos los registros relacionados. Entonces eso no tiene nada que ver
con FCR en ese momento. Así que esa es una de las situaciones
peligrosas que son
situaciones
potencialmente peligrosas que debes tener en cuenta al
diseñar una base de datos, configurar tus migraciones y llevar a cabo tus operaciones de
eliminación Solo debes saber que por defecto, dirá cascada, pero siempre puedes anular
eso para decir restringir por
defecto o cualquier cosa por el estilo
a través de configuraciones. Entonces eso es realmente todo para
nuestras operaciones de eliminación, como puedes ver, es
bastante sencillo. Sólo tenemos que ir a
recuperar el registro. Lo más probable es
que tengamos el ID para el registro que
necesitamos eliminar de todos modos, vamos y
lo recuperamos y luego solo le decimos que ese es el que
queremos eliminar, guardar nuestros cambios,
y luego eso es todo.
18. Seguimiento Vs: no el seguimiento: Oigan, chicos, bienvenidos de
nuevo. En esta lección, vamos a echar un vistazo al seguimiento versus al no
seguimiento para que podamos tener una mejor apreciación de lo que está sucediendo
en el fondo. Ya he escrito algún
código puede pausar aquí mismo, replicarlo, pero
voy a
guiarte a través de lo que está haciendo
cada línea Comenzamos con el método llamado tracking
versus no tracking. En este método, tengo
dos declaraciones, una, donde estamos obteniendo
valor de la base de datos, y solo la estoy llamando
con rastreo, y luego otra donde lo estoy obteniendo sin rastreo. Si le echas un
vistazo a las dos líneas, la diferencia que
notarás es que tengo punto como seguimiento en el comunicado. El primero es lo que estamos
acostumbrados a contextualizar equipos de punto. Quiero el primer registro
que tenga el ID dos. ¿Correcto? Eso podría
haber sido casi fácilmente un hallazgo excepto que el seguimiento de Un no funciona cuando
estamos usando un hallazgo. ¿Todo bien? Entonces, si
tuviéramos que tratar de encontrar como tendríamos eliminar
y actualizar y así sucesivamente, podemos poner Un seguimiento en
este tipo de declaraciones. De ahí mi escritura de
la primera o por defecto. Y entonces por consistencia
lo hice las dos veces, ¿no? Entonces sin seguimiento, puedo decir, dame el equipo Así que no hagas
un seguimiento después de que me hayas dado, por favor no lo rastree en la memoria, pero quiero el primero o
por defecto con ID ocho. Ahora bien, esto no parece intuitivo la forma en que está escrito porque probablemente
dirás, por qué no digo yo, dame el
primer equipo con como rastreo. La realidad es que después de la
primera declaración o por defecto, Todo esto
se convierte prácticamente en el objeto que
estamos buscando. Entonces, en otras palabras, lo
único que puedo hacer después una primera estrella por defecto y
bueno, estamos usando el acing. Así que sólo voy a envolver
eso dentro de paréntesis. Entonces después de que se
ejecute esta declaración, ¿verdad? Y solo tengo que
hacer eso porque es acc si no fuera acing, entonces no hubiera
tenido que hacer eso, pero al final de una
primera operación por defecto, vamos a empezar a
interactuar con los campos reales que
están en el objeto. Entonces es por eso que ese
seguimiento de Ano simplemente no puede venir
después de esa declaración. Entonces tenemos que decirle
al contexto DB que mire dentro de la tabla de equipos, no rastree los ítems, pero quiero el primero
que cumpla con esta condición. Esa es la declaración.
Ahora bien, la verdadera ventaja no rastrear es que en realidad libera memoria un poco más y acelera el
rendimiento porque
puedes imaginar que si
estás recuperando 100 registros todos con rastreo, entonces FCR va a tener que
estar monitoreando 100 registros,
y eso es solo por una solicitud ¿Qué pasa con todos los
cientos de registros que
podrías estar haciendo malabares en
el sistema, verdad Entonces entonces el motor FCR tiene que trabajar con el tiempo para estar rastreando todos
estos todo el tiempo Entonces en una operación simple como tal vez solo estás haciendo
una lectura en la lista, como si estuvieras listando cosas en
la base de datos a tu usuario. Siempre puedes
decir que no hay seguimiento porque no tienes que rastrear. Cosas que están en una lista
simple, ¿verdad? En su momento, sin embargo,
cuando estás a punto hacer un cambio y haces
una declaración como esta, entonces sí, el rastreo
estará ahí. Sigues adelante y
lo eliminas o incluso en la actualización, el seguimiento estaría disponible después del hallazgo para
que pudiéramos arrepentirnos, ese es un método equivocado
para que pudiéramos, aquí vamos, hicimos el cambio, y luego se está rastreando en ese momento para ser salvado, ¿verdad? Pero entonces, para operaciones de
lectura grandes, siempre se
puede utilizar el
seguimiento de Ano para reducir la atención que FCR tiene que
prestar a cada registro que
se está recuperando Ahora bien, lo que he hecho después recuperar el con
y sin rastreo, he hecho cambios en
sus respectivos nombres Entonces voy a mostrarles que en realidad podemos
mirar las entradas. Entonces tenemos esta cosa llamada un rastreador de cambios como
parte del contexto, que básicamente nos
va a mostrar información sobre qué entidad
se está rastreando, cuál es el estado de la misma justo
antes de los cambios de guardado, y luego vamos a
darle otro
vistazo después de los cambios de guardado. Solo hice esto como precaución, pero estoy seguro de que esto se actualizará después
de todos modos Pero ya veremos Bien. Entonces sigamos adelante y ejecutemos. He establecido un punto de ruptura en
la línea de guardar cambios, y tengo las
variables en el reloj. Entonces tengo las entradas
antes de guardar y después de guardar. Entonces, si echo un vistazo a
las entradas antes de guardar, me dará
la vista de resultados, y me está mostrando
que solo uno de los registros que está rastreando
como modificado, ¿verdad? Entonces si me explico, verás que se modifica
la entidad
estado aquí estado. De hecho tenemos algunas
enumeraciones que nos ha dado FCR, donde podemos decir
entidad estado punto y has modificado
agregado eliminado Cualquier cosa que prácticamente pudiera hacer
en un contexto crudo, podemos decir qué
cambio está a punto de
salvarse o
en qué estado se encuentra justo antes de que esté a
punto de salvarse. Vemos aquí ese
registro con ID dos, está en estado modificado. Registro con ID dos fue el que
recuperamos con camiones Hicimos el cambio, y
luego justo antes de guardar, ve que es el único necesita guardar porque no
estábamos rastreando el
registro con ID ocho. Entonces no importa qué
cambio le hayamos hecho, simplemente no le importa. Entonces ese sería
el escenario que nos
dio esta situación donde
tendríamos el registro, sabemos todo
sobre el registro, pero luego tenemos que
decirle al contexto que este equipo o este registro
necesita ser actualizado,
momento en el que
comenzará a rastrearlo. Entonces mientras estaba aquí, no
estaba siendo rastreado. Este objeto se encuentra en el mismo
estado que este objeto, simplemente no está siendo rastreado por EFC No obstante, si tuviéramos que poner en el comunicado de actualización manual
para sin seguimiento, entonces para cuando llegue aquí, también estaría listado como un registro
modificado para ser guardado. Todo bien. Así que voy
a pasar simplemente ese
paso y luego hacer dos pasos más para que podamos
ver las entradas después de guardar, y las entradas después de guardar. Ahora, solo tiene sigue rastreando el hecho de que tenía
esa entrada antes del guardado. No, se encuentra en un estado inalterado. Entonces, después de guardar los cambios, se mueven de cualquier
estado en el que estuvieran agregados eliminados o modificados, y pasaron a
un estado sin cambios. Entonces eso significa que el marco de la entidad todavía lo
está rastreando ¿verdad? Una vez que se enumera
aquí en las entradas, eso significa que se está rastreando. Entonces, hay momentos
en los que podrías encontrarte con algunos problemas de concurrencia cuando tal vez estés realizando una operación y luego guardas
los cambios en el registro, y luego probablemente intentes
manipularlo nuevamente
inmediatamente después, y luego podrías
obtener un error diciendo que esto ya está siendo
rastreado por el curso EF Entonces esa es una de
estas situaciones. Entonces a veces hay que
liberarlo de ser rastreado, pero no vamos a
entrar en ese nivel de complicación,
al menos no en este momento. Por ahora, solo
queremos enfocarnos en lo que hace el seguimiento de
manera diferente a la ausencia de rastreo. Entonces como dije, en
un escenario donde solo
necesitas datos para fines de solo
lectura, entonces como ningún seguimiento crea un
escenario muy eficiente para ti. Bien.
19. Consulta las relaciones de una sola con muchas: Oigan, chicos, bienvenidos de
nuevo en esta lección. Queremos
revisar rápidamente nuestra relación uno a muchos y
cómo FCR
facilita la vida al definir este
tipo de relación y permitirnos interactuar
con registros relacionados Entonces solo como un resumen, tenemos nuestra tabla de liga
definida como este modelo de datos, y tenemos nuestra tabla de equipos
definida a la derecha Entonces sabemos que al seguir
nuestra convención de nomenclatura, en
primer lugar, FCO pudo
inferir que
existía una relación de
clave extranjera entre ¿Qué es esa convención de nomenclatura? Bueno, en primer lugar,
habría indicado que el nombre de campo es ID de
liga. Todo bien. Entonces tenemos la tabla llamada
Liga y la clave foránea. Con sólo llamarlo League ID, en realidad infería que existe una relación de
clave extranjera Entonces solo como ejemplo, si no incluyera esa propiedad de navegación
virtual, esto todavía sabría que hay una
clave foránea solo por la convención
de nomenclatura que he empleado
en este momento Ahora bien, debido al tipo de
datos que se está usando, estoy usando t y t por
defecto no puede ser nulo. Entonces te darías cuenta de que
esa migración que se generó tendría un nullable Aquí está League
ID fue la columna,
y un ullase cae, y un ullase cae, lo que
significa que no puede ser
nulo en la base Bueno, C sharp admite tipos de datos
anulables. Si dijera en signo de interrogación, entonces eso
automáticamente sería anulable Entonces solo voy a ejecutar
una migración solo para mostrar. Entonces esta es nuestra migración agregar
migración hizo que el ID de
liga sea anulable Y luego en este
nuevo archivo de migración, se ve un poco
diferente al anterior, y vamos a estar
pasando por más migración. Así que todavía no me estoy enfocando en lo que
estamos viendo. Sólo quiero destacar que la columna alter está
viendo ahora que nullable
es igual a true, todo porque ponemos
ese signo de interrogación I C sharp, si haces que
el tipo de datos sea nulo, entonces así es como sabrá
FCR que
es nulo o nullable en SQL debería ser cierto, más o menos,
¿verdad Entonces es decir que el tipo
viejo nuevo tipo es TS, pero ahora es anulable Entonces esa es una de
las formas en que podemos hacer que
una clave foránea sea anulable Entonces, ¿por qué querrías
que una clave foránea sea capaz? En una situación como esta, tal vez puedas tener un
equipo sin liga. Entonces más adelante vamos a
agregar más mesas, una de las mesas que
vamos a agregar es un entrenador, un entrenador puede ser entrenador. Bueno, técnicamente, un entrenador
puede ser entrenador sin equipo porque mi
profesión es que soy entrenador, pero no tengo un
entrenador de equipo en estos momentos. Entonces estoy en la mesa de entrenadores, pero simplemente no tengo equipo. Entonces en ese punto, ese ID de
equipo tendría que ser nulo si no estoy empleado para un equipo en
ese momento en el tiempo. Entonces ese es solo un ejemplo rápido que veremos más adelante. Pero por ahora, solo quiero
centrarme en el hecho de que
podemos hacer que esa clave
foránea sea anulable Ahora, volviendo a
nuestro equipo, modelo de datos, he hecho un ligero ajuste
donde he eliminado el entero para la clave foránea y lo he reemplazado con
solo la propiedad de navegación. Eso también va a intentar generar un campo de clave
foránea leable El único problema aquí mientras que el campo de clave externa se
generará en la base de datos sin tener
la propiedad en la clase, no
hay manera de obtener ese valor entero o interactuar
con ese valor ID, ¿verdad? Entonces es por eso que
para mí hacer la vida más fácil, lo mejor es
interactuar con ambos. Ahora, lo he hecho cognoscible, pero no necesariamente
quiero mantener esa cadena Entonces lo que voy a hacer en la consola del administrador de paquetes
es eliminar la migración. Así que probablemente vimos eso
antes cuando estamos viendo todas las opciones o todos los comandos
que podemos ejecutar. Entonces para hacer esta acción, dice
que está
aquí mismo, eliminar la migración. Por lo que eliminar migración siempre
intentará eliminar la última o la más
reciente migración realizada. Entonces ahí está nuestra migración más
reciente. Yo sólo puedo decir eliminar migración, y va a matar ese archivo. Tenga en cuenta, sin embargo, que
si y ve están diciendo que se revertió y está haciendo todo lo que
sabe que necesitaba Entonces lo único sin embargo, es que si ya has comprometido esa migración
a la base de datos, y eliminé la migración se vuelve
un poco más difícil. Pero eso es algo que también
veremos, así que no te preocupes por
eso todavía. Ahora bien, una cosa más
que quiero señalar sobre estas relaciones clave foráneas es el hecho de que por
el lado de la liga, puedo agregar una propiedad que es una colección de artículos
que sé que están relacionados. Entonces, cuando andamiamos
la base de datos, probablemente tomaste
nota del hecho de que la liga tenía una
colección, y colección Entonces esto puede ser una colección. Puede ser enumerable,
podría ser una lista. Realmente depende de usted, pero sólo vamos a inferir que una
colección de equipo correcto Y solo lo voy a llamar
equipos significa que liga puede acceder automáticamente a la lista de equipos relacionados con ella.
Entonces, piénsalo. En general, qua, si quisieras la liga y luego querías todos los equipos de la liga, tendrías que encontrar
la liga tal vez por
ID y luego ir a comisariar
la tabla de equipos para decir,
consígueme a todos los equipos con
el ID de liga, ¿verdad O simplemente obtienes todos los
equipos con el ID de liga, pero luego tienes
que interunirte en la tabla de liga para obtener los detalles de la
liga en la que están Entonces ya estamos haciendo eso porque uno con equipo, puedo obtener los detalles de la liga en
la que
está involucrado el equipo. Veremos eso más adelante. ¿Correcto? Pero con sólo poner aquí
este tipo de colección, puedo decir, consígueme
la liga con ID uno e incluye a
todos los equipos. Entonces, automáticamente, estoy consiguiendo la liga, estoy
obteniendo el nombre, y estoy obteniendo de
2030 equipos que están asociados con la
liga todo en un solo objeto. Entonces esa es otra ventaja. Entonces voy a
agregar esta propiedad, y la voy a dejar ahí. Puedes hacer lo mismo
en tu modelo. Y lo último que realmente
quiero señalar es que
quiero reiterar la importancia de seguir las convenciones de
nomenclatura Cuando no sigues
las convenciones de nomenclatura, en realidad
estás luchando
contra un sistema que está diseñado para
ayudarte a hacer las cosas mejor Entonces en esta situación particular, me refiero a decir
la clave foránea. Creación porque podrías tener otras ideas en cuanto a lo que quieres nombrar a esta columna de clave
externa. Y no voy a decir que no. Sus reglas comerciales
pueden requerir
que use otro nombre de columna. Pero entonces se vuelve
difícil porque si quería nombrar a esta liga FK, y sé que esto
va a romper algún otro código que
tengo en otros lugares. Pero si lo hiciera, lo que
pasaría es que cuando
ejecute la migración, todavía va a
generar una columna llamada League ID porque FC está
siguiendo su propia convención, y entonces esta va
a ser una columna aleatoria. Una columna aleatoria llamada
liga FK que no tiene absolutamente ninguna afiliación
con la clave extranjera Entonces, una vez más, solo
quiero reiterar, seguir estas convenciones de nomenclatura, y la vida te será
mucho más fácil Ahora, en la siguiente lección,
vamos a ver la relación de muchos a
muchos, y voy a profundizar un
poco más en algunas de las cosas increíbles
que FCR puede hacer por ti
20. Añadir muchas relaciones: Oigan, chicos, bienvenidos de
nuevo. En esta lección, queremos empezar a mirar de
muchas a muchas relaciones. Ahora bien, el caso para def relación de muchos
a muchos sería cuando se
tienen muchos bien, muchos registros
relacionados con muchos registros Dentro de nuestro contexto de nuestra aplicación futbolística,
o base de datos de fútbol, tenemos que tomar en
cuenta el hecho de que van a ser muchos
partidos entre muchos equipos. Tantos equipos jugarán contra muchos otros equipos a lo largo de la
duración de una temporada. Tengo en pantalla una app muy
útil llamada raw dot IO. Es una aplicación web, y es
completamente gratuita para su uso. Y lo que vamos
a hacer es visualizar nuestra estructura de datos Así que solo voy a usar
rectángulos, agradables y simples, y voy a
llamar a esta liga una y vamos a
llamar a este equipo Entonces sabemos que tenemos
ligas relacionadas con equipos. Agradable y sencillo solo usando
una r para conectarlos. ¿Todo bien? Entonces tenemos
liga y tenemos equipo. No, necesito una nueva
entidad en la mezcla, y voy a
llamar a esta Mach Ahora, un partido
va a comprender, y yo sólo voy a escribir los campos y las entidades. Ya sabemos lo que hay
en liga y equipo, pero este
va a tener una identificación. Por supuesto. También va a tener equipo local y equipo visitante. Podemos decir que no, me estoy
alejando de la convención de nomenclatura, Así que equipo local equipo visitante, y
probablemente vamos a tener tiempo. Como dije, vamos a
terminar con el mismo equipo local, siendo
el mismo equipo local varias veces y el mismo equipo siendo el equipo
visitante varias veces, pero están siendo
boxes entre sí. Así que esta relación de
muchos a muchos realmente necesita lo que
llamamos una tabla de enlace, que es una mesa que va a quedar entre las dos tablas
relacionadas. En esta
situación particular, sin embargo, los demasiados son realmente entre muchos equipos
y muchos equipos. Entonces eso significa que tenemos tenemos equipo siendo
relacionado con esta tabla dos veces,
Entonces, perdóname si eres nuevo
en el desarrollo de bases de datos, pero así es como va. A veces tienes
dos claves foráneas a la misma mesa de
otra mesa, ¿verdad? Entonces una mesa tiene dos claves
foráneas aquí. Tenemos una clave foránea
para el equipo local, sin embargo, una
clave foránea para el equipo camino. Pero entonces esto
realmente está diciendo que muchos equipos están relacionados con
muchos equipos, muchos a muchos. Todo bien. Todo bien. Entonces ahora que he
visualizado cómo debe
verse
esta estructura de base de datos y esta nueva tabla, podemos repasar y crear
los modelos para esto Así que he seguido adelante y he creado una nueva clase a la que
voy a llamar match. Y al igual que son sus
contrapartes, va a tener
ciertas convenciones de nombre. Ahora, antes de seguir adelante,
solo quiero señalar que cada mesa o cada
modelo básicamente tiene este ID. Y luego hay
momentos en los que vas a tener de múltiples campos que probablemente se
repitan en todas las tablas, como tal vez cuando estás
haciendo auditoría o, ya sabes, tienes fecha creada, ese tipo de campos que tal vez todos necesitan
tener, porque claramente, todos nuestros campos, siguiendo
la misma convención, todas nuestras tablas, perdón, tenemos un campo llamado ID. Ahora bien, no quiero seguir repitiendo esto en
cada uno porque, ya sabes, si tenemos 20 tablas, entonces son 20 copias de
la misma línea de código. Entonces lo que tiendo a hacer
es agregar lo que llamo, déjame llamarlo vamos, y luego voy a agregar
una clase dentro de vamos la que llamo objeto de
dominio base. Esto tampoco es una
convención de nomenclatura. Yo solo lo llamo objeto de
dominio base. La gente lo llama objeto de datos
basado, gente lo llama
objeto base, sea lo que sea. Pero esto realmente
solo va a ser una clase abstracta pública. Sólo lo estoy haciendo abstracto
porque cuando es abstracto, no
puedo
instanciarlo por Es realmente un failsafe para mí, pero no
necesariamente tiene que serlo Pero voy a tomar
esta propiedad ID,
colocarla dentro del objeto de dominio
base, y luego cualquier otra entidad puede heredar del objeto de dominio
base Entonces de esa manera, no necesariamente tengo que repetir los campos. Si el nombre del campo cambia, al
menos los
campos comunes a través de todos ellos, solo
tengo que hacer
la actualización un lugar, pero todos están heredando
de ese lugar, así que todos obtienen el campo Muy bien, así que
voy a hacer eso por mucho. Entonces no hay partido. Por defecto tiene un equipo de campo ID. Y no lo voy a
quitar del equipo, pero voy a
dejar que el equipo herede. Y entonces lo que
vas a notar ahora es que va a
empezar a quejarse de
que está viendo ID tanto aquí
como en la clase heredada Entonces eso significa que puedo
quitar la identificación de manera segura de esa clase. Entonces eso es solo un pequeño truco que si aún no estás
practicando eso
puedes poner para
asegurarte de que no repitas demasiado el código. ¿Todo bien? Entonces, sigamos adelante.
Tenemos el ID de partido. Ahora necesito una propiedad que
represente a mi equipo local. Voy a
llamarlo ID del equipo local. Una vez más, esto se está
rompiendo con la convención de nomenclatura. En el video anterior,
habría mencionado lo importantes que son
las convenciones de nomenclatura Pero hay
situaciones en las que
realmente no puedes seguir la convención de nomenclatura
porque cuando llamo al equipo
local y al ID del equipo visitante, CR no lo sabe o
no va a inferir que esto significa que me refiero al equipo y esto significa que
me refiero al Entonces veremos cómo navegar
eso en un momento. Todo bien. Entonces solo agregando el resto
de las propiedades, he agregado las
propiedades de navegación que
corresponderán con
cada clave externa. Entonces tenemos clave foránea, tenemos clave foránea, y
luego tengo la fecha y hora. Entonces cambié a fecha
en lugar de hora porque la fecha puede
capturar fecha y hora. Entonces sabremos la fecha
y la hora del partido en contraposición a mi
diseño inicial, que solo decía la hora. Ahora que tenemos definida esta nueva
clase o modelo. Sabemos que tenemos que sumar
al contexto DB.
Tenemos que hacérselo saber. Solo voy a
duplicar eso y agregar el nuevo modelo al conjunto de DB
y lo estoy llamando coincidencias. Pero tengo que hacer
algo extra. Entonces, una vez más, me he separado de las convenciones de
nomenclatura recomendadas Tengo que hacer un trabajo extra
para que sepa que oye, se supone que
eres una clave foránea. Entonces, sigamos adelante y ajustemos el modelo de equipo para hacerle saber que
debe tener dos listas, una lista llamada partidos en casa y una lista llamada partidos fuera de casa. Ahora, recuerden que hicimos
algo similar por una liga. Tenemos equipo haciendo referencia a la tabla
de la liga. Entonces sabemos que un equipo
pertenece a una liga. No obstante, una liga
tiene múltiples equipos. Entonces de la misma manera, un partido puede tener un equipo local
y un equipo visitante. Entonces uno, uno, uno a la vez
para cualquier registro o fila. Pero luego un equipo, puede tener muchos
partidos fuera de casa y partidos en casa. Entonces es por eso que tenemos que
asegurarnos de que
ponemos en estas propiedades de
navegación de lista. Ahora, a partir de esto, tenemos que hacerle
saber a Entity Framework que todo ese cableado significa que existe una relación de clave
externa entre equipo y partido. Hasta ahora, claro, todavía ajeno a todo eso Entonces, lo que voy
a empezar por hacer es sobreponer nuestro método de creación de
modelos Entonces tenemos configurando. Esto significa que siempre
que estés configurando el contexto, esto es
lo que debes hacer. Bueno, esto está diciendo,
siempre que vayas a crear el modelo
o hacer una migración, la próxima vez que estés
haciendo una migración, asegúrate de tener estas
reglas en su lugar. ¿Todo bien? Entonces no quiere decir que cada migración repetirá el código para estos, pero solo significa que cada vez que
estás construyendo la base de datos y lidiando
con la base de datos, esto es lo que quería hacer. Entonces para eso
está realmente ahí este método. Entonces voy a eliminar
esa línea por defecto, y luego vamos
a tener que dejar el constructor de modelos
sepa que nuestra entidad. Así que estamos usando API fluida en este punto para
definir ciertas reglas, y verás por qué se
llama API fluida. Entonces nuestra entidad llamó equipo, Y luego solo estoy rompiendo la línea para que
no vayamos demasiado lejos. Y vamos a decir punto, y luego vas a ver
un montón de opciones aquí. Ahora, me he dejado
llevar y probé
cada combinación, pero no todas las combinaciones
funcionan realmente. Así que solo tienes que
saber lo que estás haciendo. Entonces en esta situación,
quiero decir que mi equipo tiene muchos Muy bien. Y luego solo definimos
una expresión Lambda, punto, y voy
a decir partidos en casa. Un equipo tendrá
muchos partidos en casa. Eso es cierto. Después vamos
a la siguiente línea con uno. Lo que va a inferir
en este punto, no, es que vas a tener muchos partidos en casa con un punto, y luego estamos viendo
propiedades de los partidos de casa o de
la entidad de
partido, ¿ves eso Entonces por eso es
fluido porque cada línea se
basa en la línea anterior. Entonces un equipo tiene muchos partidos en casa, y luego todos los partidos o un partido entero un
partido solo tiene uno, y voy a decir, si estoy
lidiando con partidos en casa, entonces solo tiene un equipo local. ¿Correcto? Y entonces voy a tener que decirle
eso y tiene otra vez
una
expresión Lambda de clave foránea, punto M, y luego puedo especificar qué clave foránea
facilita esto tiene muchas con una relación de la
que le estoy hablando. Voy a decir que la
clave foránea es la identificación del equipo local. Y espero que
empieces a ver que ya sabes, nombrando correctamente tus columnas Si no puede ayudar a FCR a
averiguar lo que quieres, te ayuda a descubrir
qué necesitas hacer más adelante También voy a
agregar una restricción para decir que se requiere, y para finalizar, voy a definir el comportamiento de recuperar Ya discutimos
el comportamiento de undelete donde sabemos que es una
configuración para la base Voy a decir cascada. Eso significa que si borro a un equipo, quiero que todos
los partidos vayan con él. Eso puede o no
ser lo que quieres
hacer porque tal vez
para los archivos, querrás mantener al equipo y todos los datos del partido alrededor. Eso depende de usted y de sus reglas de
negocio, por supuesto. Así que voy a repetir todo esto para el equipo visitante. Y verás que
ambos son idénticos. La única diferencia realmente es
que guardé cerillas y columnas basadas en
distancia donde
estaban las columnas de casa. Y eso es
más o menos para definir las reglas alrededor de tantas
a muchas relaciones. Así que hay
bastantes veces que quizás tengas que ensuciarte
las manos así. En esta situación,
es una muy singular
porque una no estamos siguiendo convención de nomenclatura
con nuestras claves foráneas, y dos, es la misma tabla relativa a otra tabla dos veces En otra situación,
y digamos, sólo
voy a darte
un escenario abierto aquí. Teníamos una mesa para
guardar los productos. Teníamos una mesa para
almacenar clientes, y luego tenemos
otra mesa para almacenar los productos que
los clientes han pedido. Así que muchos clientes pueden
pedir muchos productos. Por lo que esa
mesa intermedia necesita tener el ID de cliente y
el ID del producto. ¿Todo bien?
Piensa en ese escenario. Ahora, en ese escenario, es
una relación agradable y limpia. Es una relación más fácil definir que lo que
teníamos que hacer aquí. Y luego en esa
situación, realmente, solo
necesitas poner la propiedad de navegación de
listas en cualquiera de las mesas. Y entonces FCR simplemente
inferiría que hay una
tabla de productos del cliente por generar Lo siento, empecé eso hace un momento, pero debería haber una tabla de pedidos de
productos del cliente , por ejemplo,
para que se genere porque le
acabas de decir que el cliente tendría una lista de productos y los productos tendrían
una lista de clientes. Entonces simplemente sabrá
automáticamente, necesito crear una
mesa media para tantos a tantos, y literalmente, serían
muchos siendo la lista demasiados. Entonces hay diferentes
escenarios y cada escenario puede venir
con sus propias peculiares. Esta es la peculiaridad del escenario, y creo que es bueno hacer el escenario más difícil porque al
menos puedes ver lo podría tener que estar en su lugar en
caso de que te encuentres con dificultades y tu escenario no es
tan fácil como podría ser Ahora, con todo eso
dicho y hecho, sigamos adelante y ejecutemos nuestra
migración y veamos qué obtenemos. Entonces este es nuestro archivo de migración. Se trata de crear la
tabla llamada Partidos. Tenemos nuestras columnas
definidas, y luego tenemos las restricciones que
se ponen en el equipo que indican nuestras relaciones de
clave externa, ¿verdad? Así que la clave foránea número
uno entre está en la columna AA team
y es entre equipos y ese ID
y borra cascada, y es lo mismo
para el equipo local Todo bien. Entonces con
todo eso hecho, actualicemos nuestra
base de datos. Todo bien. Entonces, si actualizaste tu base de datos
tal como lo hice yo hace un momento, entonces habrías
obtenido este error. Si no lo hiciste, entonces
envíame un mensaje y hazme
saber que no lo hiciste. Pero este mensaje acaba de llegar, y como dije antes, no
voy a evitar
errores porque este es el tipo de
cosas que hacen que la gente tenga miedo de este tipo
de tecnología Entonces nos está diciendo que no pudo ejecutar el
comando DB, crear la tabla. Y si me desplazo todo el camino
hacia abajo, va a decir, estoy introduciendo una restricción o introduciendo esta restricción, puede causar múltiples ciclos o
múltiples rutas en cascada. Entonces en otras palabras, lo que está diciendo es que al tener este referencial la acción de
eliminación en cascada, sobre estas dos claves foráneas puede ser problemática para la estructura de la
base Entonces tal vez
al diseñar la base de datos manualmente, probablemente
podrías
sortearla porque nunca me
ha advertido
directamente por SQL Server sobre
algo así, pero FCR solo
te está haciendo saber que eso puede ser problemático y tiene un error al intentar
hacer eso por ti Entonces lo que podemos hacer y lo que
vamos a hacer es simplemente eliminar
esta migración para no, y siguiendo la sugerencia del EFC que este
comportamiento de eliminación es problemático, solo
voy a hacer una restricción Entonces, en otras palabras, no
puedes eliminar un equipo a menos
que hayas eliminado todos
los partidos antes. Todo bien. Y de hecho veo donde eso es razonable porque cuando lo
dije antes que eliminas a un equipo
y automáticamente borra los partidos eso
podría ser problemático, ¿verdad? Y sobre todo donde
un equipo podría estar en el ID del equipo local
o el ID del equipo A. Y entonces, ya sabes,
eso va a terminar borrando datos para equipos que aún
están en el sistema. Entonces esa fue una mala
elección de diseño de mi parte. No hay problema. I R nos ha advertido,
pero una vez más, solo
quiero ayudarte a entender lo que realmente significa ese
error. Entonces, si ves que viene ese tipo
de error, tal vez
sea porque
necesitamos cambiar ese comportamiento de
eliminación. Recuerda que va
a estar en cascada por defecto. Entonces, incluso si no
definimos cascada aquí, probablemente seguirías
obteniendo ese error. Por lo que es importante
entender cómo mitigar contra ese
error en caso de que lo consigas. Entonces intentemos sumar de nuevo
esa migración. Y esta vez lo ves
diciendo que está restringido. Eso está bien. Vamos a
actualizar la base de datos. Y esta vez,
termino y mirándolo en nuestro explorador de
servidor de objetos SQL, vemos que
tenemos
nuestro ID y tenemos
nuestras dos columnas de clave foránea
que no son leables Esa es una forma de establecer una relación de minuto
a mini. Como dije, puede diferir en
función de su situación. Dada la estructura
de la base de datos, esto es lo que tuvimos que
hacer para lograr todo esto. Estos son
lineamientos generales, por supuesto. Cuando estás creando tu relación de
muchos a muchos, básicamente
puedes seguir estas pautas y
podrías crearla sin importar crearla sin importar lo
complicada o
simple que sea.
21. Añadir relaciones en uno: Oigan, chicos,
volveremos en esta lección, estaremos hablando de mapeos de mesa
uno a uno o relaciones uno
a uno Entonces ya he seguido adelante y creé un nuevo modelo de entidad, y estamos llamando a un entrenador, y un entrenador
se utilizará para representar
el uno a uno con un equipo
porque en nuestra situación,
en nuestra base de datos, un entrenador solo
puede pertenecer a
un equipo a la vez, y por supuesto, a un equipo Tiene entrenador, ¿verdad? Pero entonces si el entrenador
es despedido mañana, entonces digamos
que ese equipo podría no tener entrenador y este entrenador
podría no tener un equipo. Entonces, ya sabes, ese tipo de reglas o restricciones comerciales
únicas pueden impulsar las reglas que colocamos o el diseño de nuestra
base de datos. Entonces, sigamos adelante. Ya tenemos entrenador heredando del
objeto de dominio base, como dijimos, objeto de dominio
base está proporcionando esa propiedad ID por defecto, lo que podemos seguir adelante y enfocarnos en todas las demás propiedades que son más únicas
para el entrenador Entonces la primera propiedad
para un autocar, como probablemente habrías
adivinado sería el nombre Ahora, no me estoy
complicando demasiado con la base de datos, pero sabemos que tenemos
un entrenador, un entrenador va a tener nombre. En este punto,
no voy a incluir más detalles
sobre este entrenador. Pero voy a incluir el hecho de que este entrenador tiene una
propiedad llamada Team ID. Por lo que este ID
de equipo como su nombre indica, será la
clave foránea de la tabla de equipos. Ahora, nuestro
equipo o mesa de equipo necesita
tener alguna representación
de un entrenador. Y lo que voy a
hacer aquí manteniéndolo muy simple es solo hacer
referencia al entrenador. Entonces así, el entrenador va a ser parte
de un equipo o, ya sabes, relacionado con un equipo, y el entrenador también la tabla de entrenadores también sabe
que está relacionado con un equipo. Voy a hacer que esto sea nulo. Ahora, cuando estaba
hablando de las reglas y demás, pasé por el
escenario de que el entrenador puede existir en la tabla
sin tener un equipo. Entonces, si no hago que
esto sea anulable, entonces va a ser requerido No siempre se requiere
porque si lo despiden, sigue siendo entrenador
solo sin equipo. Entonces lo estoy haciendo leable para que la migración sepa
que en la base de datos, esto puede ser nulo Al mismo tiempo,
en nuestra mesa de equipo, solo hacer esto, sabe
que,
bien, esto puede ser anulable, por lo que no tendrá que hacer ningún esfuerzo
adicional para Ahora,
las propiedades de navegación una vez más, te
ayudan a obtener los detalles
de las entidades relacionadas Entonces cuando consiga un equipo, puedo obtener los detalles
de la liga en la que está. Puedo obtener los detalles
del entrenador. Y puedo conseguir todos los
partidos si es necesario. Desde la perspectiva de los entrenadores, si estoy mirando al entrenador, todo lo que tengo que
seguir es una identificación de equipo. Entonces si quisiera podría incluir una propiedad de
navegación, solo
voy a copiar y pegar para moverme más rápido Podría simplemente incluir esa propiedad de navegación del equipo aquí
mismo para que
si consigo un entrenador, también pueda incluir
los detalles del equipo y todos los partidos
y todo, ¿no? Entonces echemos un vistazo a la migración que
podemos generar a partir de esto. Muy bien, entonces mi migración
agregó el equipo entrenador uno a uno. Entonces se genera nuestra migración, y solo podemos echar un vistazo
rápido y ver que
estamos consiguiendo la nueva
tabla llamada coach. Y si te has dado cuenta, en realidad
nos hemos saltado uno
de los pasos más vitales No sé si te diste cuenta, pero nos saltamos
lo que le he enseñado como un paso vital
hacia la creación de una mesa, y eso es
incluirla en nuestro contexto DB No incluimos
nuestra nueva mesa llamada coach o coaches
en nuestro contexto DB. Entonces veamos eso ahora. El hecho de que le haya dicho una tabla que está en
el contexto DB, que haga referencia a esta
clase o a alguna clase, la migración o por supuesto, sólo
va a
seguir adelante y crear una tabla que represente ese nombre de tabla. Por lo que ese nombre se está generando con base en el
nombre de la propiedad, que es coach. Entonces este podría no ser el mejor
enfoque si vamos a ser estándar con nuestra convención de nomenclatura
porque hasta ahora, siempre
hemos pluralizado
cada nombre de tabla Así que solo estoy señalando que al agregar esa propiedad de
navegación, EFCR automáticamente
va a insertar o crear toda
esa migración alrededor creación de una tabla para esa propiedad de
navegación Entonces solo voy a quitar
la migración, sin embargo, porque queremos
como que mantengamos estándar. Y voy a
agregarlo al contexto DB. Entonces tenemos una mesa llamada Coach. Rehacer la migración,
y entonces podremos sentirnos un poco mejor acerca de
lo que se está generando Entonces solo estoy
señalando ciertas cosas que FCR va a hacer
detrás de escena
aunque falte un paso Entonces quieres ser un
poco deliberado, pero FCR va a hacer
ciertas suposiciones para ti en función de cómo
sabe que necesita para operar Sigamos adelante y actualicemos
el y eso está hecho. Entonces solo quiero
señalar también que el índice create tipo de se ve un poco diferente a lo
que podríamos haber visto
hasta este punto, y tiene un filtro. El ID del equipo no es nulo. Entonces solo mirándolo, probablemente
te estés preguntando,
bien, qué significa eso, sobre todo porque le dijimos la tabla que el
ID del equipo es nulo. Bueno, si nos fijamos en
la sentencia que se generó para
el índice create, estamos creando el índice único en esa columna cuando no
es nulo. Entonces, una vez que hay un valor ahí, eso significa que no puedes repetir ese valor en ningún otro entrenador. Eso es más o menos
lo que está diciendo, pero se permite que
sea nulo independientemente. Bien. Entonces eso es realmente todo para establecer una relación uno
a uno. Una vez más, el
escenario para eso sería cuando
sabes que solo quieres que una entidad se asocie
una vez con otra entidad. Y hay diferentes
escenarios cuando tienes relaciones uno a
uno. También podría ser que uno dependa completamente de otro,
es decir, podría ser un escenario
en el que solo queremos tener un entrenador en el sistema
cuando está asociado a un equipo. Fuera de estar
asociado con un equipo, no
debería estar en la base de datos. Entonces sí tienes ese escenario
también, pero una vez más, tus reglas de negocio y
tus requisitos
impulsarán las
decisiones que tomes durante tu diseño.
22. Generar un diagrama de nuevas entidades: Oigan, chicos, bienvenidos de nuevo.
Este es un video rápido. Solo quiero mostrarte cómo
puedes actualizar tu diagrama de
base de datos. Así que hemos estado haciendo
bastantes cambios. Hemos agregado nuevas tablas,
agregado nuevas relaciones, y solo quiero
mostrarle cómo puede actualizar la representación visual de
su base de datos. Y
es bastante simple. la misma manera que lo hizo
la primera
vez, solo repites ese paso, y creará un nuevo
diagrama y lo cambiará por ti. Así que sólo tienes que
hacer clic derecho en tu proyecto. Siga adelante y vaya
a FCR Power Tools, agregue el diagrama de contexto DB Simplemente seguirá
adelante y
generará uno completamente nuevo para ti, y lo verás aquí. Entonces tenemos nuestras nuevas entidades
en forma de entrenador, y notarás que
las flechas
te están mostrando la cardinalidad de
estas relaciones, para que puedas decir de inmediato que esto está siendo visto como
uno a uno por la FCR Este es un uno demasiados, y esto también es uno demasiados. También notarás que las
propiedades de navegación se han actualizado donde un partido tiene un equipo
visitante y un equipo local. No obstante, el equipo tiene
listas de partidos fuera de casa. Y claro, si pasas el cursor sobre cualquiera de estos
bloques o propiedades, te
mostrarán qué categoría es la colección de navegación, dependiendo de la coincidencia, y
su tipo es la lista de coincidencias Entonces este es un gran diagrama de
referencia para darle a alguien que no necesariamente
entiende o quiere peinar cada clase para
ver exactamente lo que está sucediendo. Este bonito diagrama de visión general es una excelente manera de
ponerse al día con qué referencia es qué y cómo
se forman estas relaciones.
23. Inserción de datos relacionados: Oigan, chicos, bienvenidos de
nuevo en esta lección. Estaremos pasando por
algunos ejemplos de cuándo
necesitaremos agregar registros
que tengan relaciones. Entonces, antes cuando estábamos viendo
nuestros escenarios de inserción, realidad
miramos uno
y lo he repetido a continuación, que es agregar nuevos
equipos con liga. En ese escenario, teníamos una
liga que aún no existía, y luego teníamos un equipo, que tampoco existía todavía, ahí la creación, ¿verdad? Y luego agregamos este equipo mientras pasaba
en el objeto de liga. Y luego nos dimos cuenta de que cuando llamamos agregar y guardar cambios, lo que pasó es que creó la liga que aún
no existía, y luego
automáticamente insertó esa
relación de clave extranjera con el equipo. Para que puedas volver a visitar
ese video de inserción y revisar lo que sucedió cuando
hicimos esta operación Ahora, tengo algunos
otros escenarios por los que nos
gustaría pasar. Una es cuando agregamos un nuevo
equipo con el ID de liga. Y creo que este es probablemente un escenario
más indicativo de lo que sucedería en
una situación de software. Ahora, cuando estamos
agregando un nuevo equipo, agregamos nuevo equipo con ID de liga, esto es probablemente lo que va a pasar quizás desde una interfaz
web, ¿verdad? Alguien está escribiendo
el nombre de un equipo, y entonces
probablemente indicarían qué liga
pertenece este equipo a través de
una lista desplegable Entonces tendrías
este escenario si
requirieras que el usuario
ingrese ambos al mismo tiempo, ingrese el nombre del equipo
y el nombre de la liga. Entonces, sí, podrías
seguir adelante y crear manualmente los objetos y luego hacer uno guardar los cambios y
ambos se comprometen. Otro escenario más práctico, aunque sería que
tengas la lista de ligas y cuando
seleccionen de esa lista, te
harían saber, enviado sobre el ID de
la liga que se
seleccionó así como el nombre del equipo al
que están entrando. Entonces, ya tenemos algunas
ligas en nuestra base de datos. Déjame ir a
buscarlos rápidamente. Así que podemos
simular fácilmente qué ID
serían los ID potenciales para que
un usuario pueda seleccionar. Entonces digamos que querían agregar un nuevo equipo de futbol de Serre Entonces nuestro código se vería
algo más así. No tendríamos
que crear ese objeto de liga, pero crearíamos el equipo, y luego pasaríamos en
el ID de liga de ocho. Entonces en este escenario, la
liga ya existe. Sabemos que es DNI. Lo estamos
agregando al equipo. Estamos agregando el nombre
a este nuevo equipo, y este equipo
va a Fiorentina, y luego podemos
seguir adelante y agregarlo, y entonces esa relación
será fuerte Ahora, uno de los beneficios de tener relaciones y bueno, bases de datos
relacionales
están diseñadas para hacer cumplir esa
consistencia en sus datos Disminuimos el riesgo
drásticamente si aún existe de tener una liga que no existe estando
asociada a un Entonces ya miré el hecho que hacemos una eliminación en cascada. Si eliminamos la liga, entonces se eliminarían
todos los equipos, ¿verdad? Pero entonces no puedo agregar un equipo
que esté relacionado
con liga con ID 50 cuando vimos
que ocho era el máximo. CO, bueno, la
propia base de datos rechazará que
COR lo intente, la base de datos dará un error y luego la
rebotará Entonces ese es uno de los beneficios
de tener este tipo de fuerte integridad referencial
aplicada en sus mesas Hay gente a la
que no le gusta,
pero estás usando una base de datos
relacional Úsalo a tu favor. Bien, entonces ese escenario uno. Cuando Orwell dos, el escenario uno era cuando podíamos simplemente
poner todo el objeto y agregar ambos y la relación se
habría creado o esos datos relacionados se
habrían creado
en segundo plano Nuestro otro escenario,
que es más práctico sería
cuando obtenemos el ID del registro relacionado
y luego lo
pasamos al registro que
pretendemos crear. Ahora, nuestro siguiente escenario
sería cuando queremos sumar una nueva liga con equipos. Una vez más, ese podría ser un escenario en el que estés creando la liga
y, ya sabes, le das al usuario la
oportunidad de agregar una nueva liga sumar todos los equipos y
luego se someten una vez. Entonces eso significa que en esta situación, necesitas crear
el objeto para la liga y necesitas
decirle a los equipos que tiene, y al igual que como el
contexto del anuncio habría agregado ambos objetos nuevos y luego
configurar los valores relacionales, sería el
mismo escenario aquí Entonces ya
hice esa función donde estoy agregando una nueva
liga con equipos, y luego una R equipos es igual
a una nueva lista de equipos. Entonces digamos que esto es
lo que ha enviado el usuario, así
como el nombre
de esta nueva liga. Entonces se puede decir que lo
copio y lo pego, ¿no? Entonces Esta nueva liga es CFA, abreviatura para hombre Asociación de
Fútbol de la Isla Trabajemos con eso. Y estos son algunos de los
equipos que estarían en CFA. Entonces cuando añadimos esta nueva liga, que es un objeto de
tipo liga y
tiene su nombre y
su lista de equipos, marco de la
entidad hará el
resto cuando guardemos los cambios. En este siguiente escenario,
estamos buscando crear registros para nuestras
muchas a muchas tablas. Así que recuerda que
los partidos representan nuestra tabla principal de demasiados donde muchos equipos van a jugar
contra muchos equipos, ¿verdad? Entonces esta función simplemente
define una lista de tipo match, y tiene algunos partidos
con el ID del equipo
visitante, ID del equipo local y la
fecha del partido. ¿Todo bien? Ahora, estoy
haciendo un dos por uno aquí porque estamos
viendo uno cómo
crear el disco para
muchos a muchos. Y recuerda que nuestro partido o nuestros muchos muchos tabla
generalmente tendrían el ID así como la propiedad de
navegación. Entonces de la misma manera que
podríamos poner en el objeto para la
propiedad de navegación y tenerlo agregado a la base de datos,
es de la misma manera aquí. Pero en un escenario más
práctico, estos equipos ya
existirían para cuando
estemos agregando un partido. Entonces, lo que tenemos que hacer
es asegurarnos de que estamos
haciendo referencia a las identificaciones correctamente Con una
interfaz de usuario, por supuesto, restringe
los valores que el usuario puede ingresar a valores
que son más que probables que van a ser valores
válidos para reducir cualquier contratiempo por parte de la base de datos al
intentar ingresar los registros ¿Todo bien? Entonces esa es la primera parte de las 241 en este escenario. La siguiente parte es el hecho de que
estoy usando este rango add. Entonces Ponto, siempre hemos estado
haciendo publicidad. ¿Correcto? Agregar representa uno. Solo estamos pasando un objeto cuando decimos
agregar o agregar una sincronización. Sin embargo, cuando decimos agregar
rango o un rango una sincronización, entonces podemos pasar en una
colección de valores, y todos ellos solo se
agregarán una vez que guardemos los cambios. Entonces, tradicionalmente,
en versiones anteriores, probablemente
pondrás esto en un para cada bucle y para
cada uno de la lista, agregas add add add
then save changes. Ahora, Ahora, en nuestro escenario final, aquí no pasa nada realmente
especial. Ya sabemos cómo
agregar un registro. Y el hecho de que
tengamos una relación
uno a uno en
este escenario no cambia el hecho de que
es el mismo bit de código para solo agregar un registro. Entonces tenemos un entrenador y este entrenador
se llama Joseph Marino, y va a ser
entrenador del equipo ID tres. Ahora, recuerden que
en realidad este es un campo leable. Entonces digamos que teníamos dos entrenadores y uno
no tenía equipo. Entonces voy a
decir Antonio Conte, y este entrenador no
tiene equipo, ¿verdad Ahí está de la misma manera que puedo agregar a Joseph Marino
con el ID del equipo, puedo agregar Conte
sin el equipo Lo único es
que va a quedar como huérfano
existirá en la mesa, pero no tiene
relación con un equipo Entonces en cuanto sea contratado, entonces simplemente actualizamos su registro y tendrá ese
registro relacionado para el equipo. Entonces tal y como está, si ejecuto esto Vemos que ambos entrenadores ingresan
sin errores en ningún lado. Antonio sin su identificación de equipo, así
como Joseph
Marino con el suyo propio. Entonces había comentado
las otras funciones. Déjame descomentar, y luego
vamos a ejecutarlos todos y ver exactamente
lo que está sucediendo en el código Entonces intentemos eso otra vez. Bien, así que todo
se ha ejecutado sin tierra alguna. Entonces vemos que estamos sumando la
Bundesliga en la cima. Estamos agregando Barn Munich, estamos agregando Florentina,
estamos agregando Entonces se puede ver que incluso
cuando agrupamos los objetos,
el FCR, una vez más,
supo inteligentemente,
cuál es la dependencia, Insertar que obtiene su identidad de
alcance, Insertar que obtiene su identidad de
alcance, y luego usar eso para insertar
cualquier otra cosa que se Entonces aquí vemos que estamos sumando
Rivoli United junto a CFA. Entonces CFA tiene una identificación de 11, y es por eso que Rivoli y
Waterhouse Ese escenario fue que estamos sumando una liga con
la lista de equipos. Para el que tiene los partidos
donde agregamos rango, ve
que simplemente
pasó y agregó cada uno individualmente. Probablemente te estés preguntando
por qué no solo creó una instrucción insert
y la hizo línea por línea. Bueno, eso se remonta a
las operaciones a granel. El FCT decidió que a menos que se esté tratando con un
cierto número de registros, probablemente no valga la pena el procesamiento por lotes de esos comandos Entonces es por eso que para
comandos más pequeños
o menor número de registros, verá que
se ejecutan sentencias
SQL individuales para ellos. Entonces eso
es realmente todo por cómo podemos ir sobre la inserción de datos relacionados. Una vez más, esto puede parecer
poco intuitivo porque estamos codificando duro los datos y estamos usando una aplicación de
consola Pero en un escenario de
aplicación web, solo recuerda que
habrías dado tu formulario de usuario, lo que limitaría o
te permitiría restringirlos para insertar solo
valores de datos que sabes que necesitas para llevar a cabo
las operaciones de guardado. Entonces, cuando llenen
esos formularios y los envíen, extraerías esos datos. Si es que estaban creando una nueva liga con una
lista de equipos, bueno, vemos cómo podemos
lograrlo con bastante facilidad. ¿Correcto? Estas son solo pautas en cuanto a lo que puede suceder
en el back end, una vez que tienes los datos que el formulario o el usuario más bien habría
enviado vía formulario, sabes cómo construirlo
y luego enviarlo a
FCR y dejar que FCR
haga el resto.
24. (de carga Eager) incluyendo los datos relacionados: Oigan, chicos, bienvenidos de
nuevo en esta lección, vamos a estar viendo
cómo podemos recuperar datos de varias tablas
usando un solo comando. Ahora, un escenario para
eso sería si tiene un informe o alguna visualización de datos que
necesita lograr, pero luego los datos
que necesita
mostrar se
distribuyen en varias tablas. Ahora bien, uno, aquí es
donde entra
la integridad referencial porque sabes que
siempre puedes ir y obtener los datos relacionados
de otra tabla Pero entonces si estás familiarizado
con la qua tradicional, también
sabrías
que tienes que hacer alguna forma de unirte. Podría ser correcto,
podría quedar,
podría ser inérico pero hay que hacer
alguna forma de unirse en esa consulta qua para
recuperar los datos relacionados No es muy diferente
de lo que
hubiéramos visto con nuestras
sencillas consultas selectas, excepto que vamos a estar
viendo algunas cosas más. Entonces tengo la
consulta de selección simple aquí como referencia, y sabemos que
ejecutamos con eso a listar, y así es como obtenemos nuestros datos. Echemos un vistazo a
algunos escenarios que he reunido
para ver cómo
podemos jugar con todo
el concepto de incluir
datos relacionados o carga ansiosa. Entonces, en primer lugar,
vamos a ver cómo podemos obtener muchos registros
relacionados. Y el escenario aquí
es que ¿y si
quisiéramos conseguir todas las
ligas y todos los equipos? Y solo piensa en mostrar estos datos a un usuario, ¿verdad? Tienes la lista de ligas y tal vez al
hacer clic en la liga, veas a los equipos. ¿Todo bien? Entonces quieres
recuperar todas las ligas
y todos los equipos
relacionados con ellas, tal vez todo en una sola llamada, por cualquier motivo,
tu escenario puede determinar por qué
necesitarías escribir
este tipo de core. No hay problema. Entity Framework Core nos
permite hacerlo todo. Entonces lo que haríamos es
como una simple selección, vamos a decir que
las ligas son iguales a, y luego esperamos nuestro contexto, que va a
llamar a nuestras ligas, y luego simplemente vamos
a decir a la lista. Entonces eso sería lo que
hacemos para conseguir las ligas. Ahora, queremos los equipos que están asociados a las
ligas, ¿no? Entonces antes de nuestra lista, tenemos otra función que
podemos usar llamada include. Incluir nos permite poner
en una expresión Lambda. Entonces ya ves cómo funcionan
las expresiones Lambda. No, ya ves que no son
exclusivos de los filtros y así sucesivamente. Hay ciertas funciones
que utilizan expresiones Lambda. Y siempre se puede decir que una expresión
Lambda va a ser utilizada en función del tipo de datos, que es expresión funk, y luego verías la liga o el objeto de cualquier
tabla en la que estés ¿Todo bien? Entonces
básicamente estamos diciendo: ¿Qué quieres que incluya? Eso es lo que esto está
preguntando ahora mismo, y quiero incluir Q punto, y luego diría equipos. Entonces, de inmediato, vamos a ver que esta
cantera se está ejecutando para devolvernos básicamente estrella
selecta de los equipos con
las juntas
internas en los ID de equipo que coincidan con el ID liga o
el ID de liga
o en la tabla de equipos, coincidiendo con el ID de liga
de la tabla de liga Así que vamos a
echar un vistazo rápidamente a esa sentencia SQL generada. Y ahí vemos seleccionar, y luego enumera todas las
columnas de ambas tablas. Entonces ligas es L, y equipos es T, por lo que selecciona todas las
columnas entre L y T,
y luego va
a dejar unirse a equipos en el ID de liga que coincida con
el ID de liga por equipos. Entonces, debido a esa integridad
referencial que hemos impuesto, F C sabe claramente cómo
formular esa consulta para saber qué columnas deben mapearse entre sí
en esa unión izquierda Observe que está usando una unión izquierda. Eso quiere decir que si hay una liga en la
base de datos que
no tiene equipos porque estamos
consultando la tabla de la liga, va a traer de
vuelta esa liga No obstante, el
objeto del equipo será. Entonces, permítanme poner
ahí un punto de quiebre al final
de esa ejecución. Para que puedas ver cómo se verá
eso. Entonces estos son los datos que
regresan en ese objeto de liga. Y si me explico, entonces
verás ID dos, Red stra Premier League y
los equipos que están en esa Premier League de los
Rojos y
todos los detalles. Entonces este equipo no tiene entrenador. Cuenta con el ID siete. Ves que está
relacionado con Liga con ID dos, y puedes obtener el nombre. Entonces ahí mismo, puedes decir
liga objeto punto equipos punto y simplemente accede a lo que
quieras desde
el objeto ligas. Entonces ese es el poder
de nuestra ansiosa carga. Entonces tenemos algunos
otros ejemplos por los que queremos pasar
solo para mostrarte cómo puedes mezclar y combinar
y las diferentes cosas que puedes hacer
en función de tu situación. Entonces, nos fijamos en
obtener muchos registros con sus muchos
registros relacionados, ¿verdad? Entonces estamos consiguiendo todas las ligas y la lista de equipos por liga. Tal vez ese no sea el caso.
Tal vez solo quieras obtener un registro y un registro
relacionado o, ya
sabes, una lista de registros
relacionados, pero solo un registro. Entonces en esta situación, queremos conseguir un equipo
y los detalles del entrenador. Entonces para éste, voy
a decir que nuestro equipo es igual a, y esperamos o contexto. Como llama a nuestros métodos aquí. Entonces, si lo miras los equipos de
punto de contexto sí incluyen. Pero entonces como establecimos, incluso cuando decimos
context dot teams, no
hace nada hasta que ponemos
ese comando ejecutor. Ahora, sí dije que
sólo quería uno. Y si recuerdas, la
forma de obtener uno sería ya sea single o default
o first o default. En este caso, voy
a poner primero o por defecto. Entonces quiero equipo con
la identificación, digamos,
dos, y el entrenador para
el equipo con el ID dos. O digamos tres. Creo que puse en el entrenador con ID tres. Sólo podemos regresar y comprobar. Entonces equipo con ID
tres. Ahí vamos. Entonces voy a decir punto incluir luego poner en mi comando de
ejecución, que es, en este caso, primera estrella por defecto porque
ese es el ejecutor. Yo sólo quiero uno. Así que la
primera estrella por defecto toma la expresión Lambda donde
voy a especificar que
quiero que el equipo con ID sea
igual a. Tres. Todo bien. Entonces así es como encadenas
estos comandos. Solo estoy rompiendo la
línea para que veas dónde empieza realmente
cada función, ¿verdad? Entonces equipos de punto de contexto, consígueme todos los equipos. Por favor incluya al entrenador, pero luego solo quiero
el primero o por defecto donde la identificación sea
equivalente a tres. Entonces echemos un vistazo a lo que obtenemos cuando
ejecutamos esa. Bien, entonces Q que se genera es bastante
sencillo. Selecciona la parte superior, y vemos el mismo tipo de unión
que está pasando. Entonces, debido al primer valor predeterminado, estamos seleccionando el superior, y luego tenemos esa cláusula
were para filtrar hasta donde el
ID del equipo debe ser tres. Entonces espero que estés viendo atravesando el tema
común. Así que estoy de vuelta en el código
o en la ventana del reloj. Y ves aquí ese autocar, la propiedad de navegación tiene
todos los detalles del autocar. Entonces ese es el poder
de nuestro incluir. Y una cosa que
quiero señalar, que es algo que puede
frustrarse si no te
das cuenta de lo que está pasando. Donde coloques el
primero o por defecto tiene mucho que ver con si la
declaración va a funcionar o no. Simplemente te dará un error. Entonces, si pongo context dot
teams entonces primero o default, no
puedo hacer un include después un primero o default
porque un primero o default realmente
convierte esto en un objeto de tipo team, y luego todo lo que puedo acceder
son las propiedades. Porque estoy usando la sincronización A
que no se muestra,
claramente, así que déjame
quitarme el ASIC y mostrarte Que cuando digo punto,
realmente solo estoy obteniendo
las propiedades, casa coincide con ID, ¿verdad? Entonces, si eso es lo que viene si eso es lo que viene
después primero o por defecto, entonces claramente incluir no
está en esta lista. Y así terminamos con ese error de
sintaxis en ese punto. Ahora bien, en mis primeros días, no lo apreciaba mucho, y solía pensar que ese framework de
entidad tenía errores, pero de verdad y realmente importa el
orden, ¿verdad? Entonces quieres hacer todas las cosas relacionadas con la
base de datos, y luego dejas tu sentencia
ejecutora para el final. Todo bien. Entonces, una vez más, vamos a ir por los equipos,
incluir al entrenador, y luego primero o por defecto, y esas líneas rojas
son porque
necesito la sincronización A,
y ahí vamos. Bien, chicos. Entonces, para
nuestro próximo escenario, vamos a estar viendo la inclusión
de nietos Entonces cuando
hablamos de nietos, es solo cuestión
de jerarquía La primera mesa que estamos consultando, digamos
que es el padre Entonces la primera mesa
o la siguiente mesa que incluimos es el niño. Pero entonces podemos tener
múltiples inclusiones. Entonces todos los niños
son aquellos con relaciones
directas de clave foránea la mesa principal que se está consultando. Entonces esos son niños. Así podrás tener múltiples
inclusiones solo para los niños. Sin embargo, puede
llegar un momento en que necesites
datos adicionales del niño, y luego tendrás que buscar
otra tabla que esté relacionada con ese niño. Entonces en esta situación, vamos a tener que
conseguir partidos de equipo luego. Y luego cuando conseguimos
los partidos, ya sabes, o
llegamos a casa,
o partidos fuera de casa. Pero entonces necesitamos los detalles
del equipo contrario. Entonces, si soy el equipo local, necesito los detalles
del equipo visitante. Si soy el equipo visitante, necesito los detalles
del equipo local. Entonces voy a tener que entrar en los nietos
porque los partidos
tendrán las propiedades de navegación para el equipo local
así como su equipo visitante. Entonces, una vez más, dejamos nuestro método de
ejecución para el final, y hacemos todas nuestras inclusiones
antes de llamar a esa parte
final del mismo. Entonces voy a comenzar
con un incluir cuatro,
cuatro nuestros
partidos fuera de casa. Todo bien. Entonces soy el equipo número uno. Queremos ver todos
los partidos de AA. Y entonces podemos ver eso. Pero luego cuando incluimos
los partidos de visitante, todo lo que estamos viendo son
los detalles del mismo equipo que conseguimos, pero no sé otra
cosa que la identificación del equipo local. Entonces puedo encadenar y decir, luego incluir luego
incluir me da acceso a las propiedades
del niño. Entonces include me dio acceso a la propiedad de navegación de la tabla o al objeto
que representa la tabla. Yo me di acceso a esa propiedad
de navegación. Ahora, quiero incluir una propiedad de navegación
en ese niño. Entonces puedo decir luego incluir y usar la expresión Lambda
una vez más y decir Q punto, y puedo buscar el equipo
local. Ahí vamos. Entonces tengo partidos de Día y
de los Partidos Fuera, que es de tipo match. Quiero incluir detalles
sobre el equipo local. Bien. Por otro lado, y ya dije antes que todos los niños se pueden
incluir uno al lado del otro. Entonces sí tengo esto incluir, y luego tengo esto
luego incluir, ¿verdad? Entonces, lo que voy a hacer, no
quiero
confundir el tema Déjame mostrarte
múltiples inclusiones para múltiples
propiedades de navegación antes de mostrarte a los nietos Entonces acabamos de ver un ejemplo
del nieto, ¿no? Pero solo estoy dando
un paso atrás y mostrándote que
puedes decir incluir tantas veces como necesites para incluir propiedades directamente
relacionadas. Entonces puedo decir, consígueme los equipos y por
cada equipo que me consigas obtener sus partidos y
todos sus partidos en casa. Una vez más, sin embargo, cuando es un partido en casa cuando
es un partido fuera de casa, necesito los detalles
del equipo local. Cuando es un partido en casa, necesito los detalles
del equipo visitante. Entonces puedo decir, después de incluir
los partidos en casa, quiero que incluyas los
detalles del equipo local. Y de la misma manera, cuando se
trata de un partido en casa, quiero que luego incluyas
los detalles del equipo visitante. Y entonces podemos
llamar a nuestra ejecutora. Entonces ya sea que lo llamemos primero
o por defecto o para enumerar, pero el punto es que es nuestra consulta para conseguir a
nuestros nietos Y entonces la cosa
es que realmente puedes encadenar esto
porque, ya sabes, según la configuración de tu base de datos, puedes tener
varias tablas con hijos sobre hijos o claves
externas sobre claves externas. Siempre y cuando tengas involucrada una clave
foránea, puedes decir luego incluir,
puedes incluir. Pero luego recuerda que el
include te permite hacer
referencia directa a las claves foráneas
relacionadas con la tabla principal. Y luego por cada
incluir, puedes decir, luego incluir, y luego puedes continuar
incluyéndote e incluyendo. Y notar que luego incluyen no
me impide hacer una
inclusión después, porque aunque hiciera
todo eso en una línea, es un poco menos legible, razón por la
cual la
rompí en dos líneas. Pero ya ves, estoy diciendo,
consígueme los equipos. Incluir la forma de los partidos.
Entonces incluye esto. Entonces voy a volver a incluir. Pero obviamente, el
entonces include
solo puede seguir el include
porque no puedo entonces incluir después de una
tabla que no
tiene la propiedad de navegación que estoy buscando y espero
encontrarla, ¿verdad? Entonces incluyo la forma en que los
partidos, entonces digo, cuando consigues los partidos de la manera, luego incluyo al equipo local
por la forma en que coincide con los objetos. Entonces sigo adelante y digo, también incluyo prácticamente
los partidos en casa. Y cuando incluyas
eso, quiero que
luego incluyas los detalles del equipo
visitante. Después de que hayas formulado
todo eso, solo
quiero el que
tenga identificación de uno. Así que vamos a dar una
vuelta a eso y ver qué obtenemos. Entonces, en primer lugar, prestemos atención al SQL
que se está generando. Tenemos todas las mesas
que estamos recibiendo. Entonces ya ves, selecciona T cero, T cuatro, T dos, todos esos están ahí. Y luego tenemos de, pero
luego está usando una sub consulta. Entonces consultamos a los equipos donde
el ID es igual a uno, y a eso lo llamamos t cero. Luego nos fuimos a unirnos a eso, y luego
seleccionamos entre los partidos, y luego
lo estamos volviendo a unir a los equipos ¿Verdad? Entonces, la complejidad
del SQL variará en función de cómo se establezcan realmente
las relaciones. En esta situación,
es casi como una referencia circular porque
estoy mirando a un equipo, y luego estoy diciendo, ya sabes, cuando estoy mirando partidos, por favor regresa y
trae de vuelta al equipo. Entonces es como volver a
la mesa del equipo,
lo que acaba de consultar. Pero esa es solo una situación
con la
que tenemos que trabajar cuando estamos haciendo este
tipo de cosas. ¿Todo bien? Pero entonces una vez más, no
tienes que lastimarte la cabeza por
tratar de resolver esto porque
FCO lo generó para ti Ahora bien, lo que devuelve es el equipo con partidos
y oponentes, y eso debería haber
sido disculpas por el equipo Pero entonces tenemos los
partidos AA, que es sólo uno. Por lo que este equipo con ID uno, que es Juvento sólo tiene un partido AA y un partido en
casa. Bien, bien. El partido de visitante,
conocemos el camino equipo. Eso está implícito porque
incluimos los partidos del Camino. Entonces sabemos que somos el equipo visitante. Jovents es el camino en equipo.
No necesitamos esa. No obstante, sí necesitábamos los
detalles del equipo local, y lo conseguimos. Entonces aquí vemos que
es InterMilan. Y creo que Jvento
tiene una buena oportunidad porque ni siquiera
tienen entrenador, ¿verdad Entonces Javent podría simplemente
ganar ese partido fuera de casa. Si nos fijamos en los partidos de casa, es la misma situación. Somos el equipo local. Estos son los partidos de casa. Entonces obviamente Javent
es el equipo local. Pero si miramos al equipo visitante, vemos que el equipo
visitante es Asma, y el entrenador es nulo, pero luego si hubiéramos
incluido al entrenador. Entonces, ¿y si quisiéramos incluir
al entrenador junto a esto? Entonces ese es otro
solo hagamos eso. Entonces, ¿y si por cada equipo
que estamos incluyendo, queremos ver quién es el entrenador Queremos los detalles del entrenador. Entonces puedo decir, una vez más, hacer luego incluir Así que cuando
incluyas al equipo local, quiero que luego incluyas Q, y luego veas que está
bajando de la cadena y dándome las
propiedades de navegación de acuerdo a lo que sigue en la fila. Entonces solo puedo decir luego
incluir al entrenador. Y entonces esto traerá de vuelta los detalles del entrenador de
ese equipo. Entonces déjame hacerlo otra vez. Y estamos en medio de
mirar los partidos de casa, así vemos que
somos el equipo local. El equipo A es A Roma, y el entrenador de AsRMA es Joseph Moreno.
Entonces ese es un buen entrenador. Vamos a tener que sacar nuestro juego A para ganar
ese partido en casa. Así es como puedes
seguir adelante y encadenar tus inclusiones para asegurarte de que estás obteniendo todos los datos de todas
las tablas relacionadas. Y esta es otra
fortaleza de tener la integridad
relacional
debidamente implementada y trabajar con FQ Por supuesto que está
tratando de hacer tu vida lo más fácil posible. Así que esto acaba de reducir un montón de combinaciones y juntas
internas para ti porque
si nos fijamos en ese SQL, solo
se hizo un poco más grande
porque ahora tenemos que unirse internamente o dejar unirse
al entrenador en la mesa. Me doy cuenta de que está diciendo forma
interna y se fue para suma. Entonces es saber automáticamente
que si es anulable, entonces es una unión a la izquierda
porque eso significa que puede que no
haya nada
en ese lado de la mesa No obstante, cuando no
es anulable, sólo
va a hacer un interior
porque sabe que
tienen que ser una coincidencia absoluta para mí para traer de vuelta Tenía estos otros dos
ejemplos destinados, pero creo que los
agotamos todos con
estos tres porque
estos tres son bastante
completos en cuanto lo que están representando que puedes hacer a la hora de incluir Este dice con filtros, ya
filtramos aquí. Pero la idea principal detrás mostrarte uno con
filtros sería que si yo fuera a decir consigue todos los
equipos con partidos en casa. Entonces es un simple de consulta. Esperamos a los equipos de punto de contexto, y voy a agregar la cláusula
where para mi filtro, y luego aquí solo estoy
diciendo partidos en casa, que sabemos que es un
recuento de puntos de lista es mayor que cero. Entonces eso significa,
consígueme a todos los equipos que tengan al
menos un partido en casa, y quiero incluir a su
entrenador. Y claro, es A. Así que esa es la sentencia SQL
que se genera para nosotros. Puedes sentarte y
echarle un vistazo,
claro , si es necesario. Pero luego vemos que tenemos
tres equipos regresando que no tienen
partidos en casa programados. Entonces podrías sentirte tentado
cuando miras los datos,
podrías tener la tentación
de decir, Bueno, ¿por qué no solo verificamos
si los partidos en casa son Y quiero decir, yo entendería porque estamos diciendo que home matches.com es
mayor que cero Y si hubiera dicho, ho mucho es equivalente a null, ya que esos son los
datos que vemos, pero ¿cómo exactamente FCO
sería capaz de
traducir este
objeto de lista a nulo Porque recuerda que SQL
no sabe
nada de listas y
listas que son nulas. Entonces, si miramos
la sentencia SQL que se está generando para esto, bueno, en primer lugar, no hay
datos que regresen, ¿verdad? Entonces esa consulta, sea cual sea
la consulta que se genere, no
está trayendo de vuelta
datos que esperábamos. No, si miramos la
consulta SQL que se generó, vemos que es una
consulta de selección regular con la unión izquierda, pero entonces este filtro simplemente la está
lanzando hasta el final. Entonces eso es por supuesto,
forma de decir, no
puedo No puedo entender lo que quieres que compare
en esta situación, ¿verdad? Entonces, si bien es posible que no hayamos recibido un error de sintaxis ni
ninguna forma de advertencia, solo
queremos tener cuidado cuando agreguemos nuestros
filtros, y, ya sabes, podríamos ponernos un
poco más celosos con la forma en que
lo estamos haciendo, y eso Es bueno experimentar,
pero solo ten cuidado. Entonces eso es realmente para
nosotros explorando
cómo consultar registros relacionados. Y como de costumbre,
voy a dejar ahí
ese método para que
puedas referirlo más adelante. Yo sólo voy a limpiar lo
que no pasamos, y tienes esos ejemplos
para revisar después.
25. Proyecciones y tipos de datos anónimos: Oigan, chicos, bienvenidos de
nuevo en esta lección. Estaremos echando un vistazo a proyecciones y tipos de datos
anónimos. Ahora, probablemente estés viendo
este tema y preguntándote, bien, ¿de qué
estamos hablando exactamente aquí? Un estudio de caso para esto sería que tienes todos
tus modelos seguros, pero luego quieres
datos específicos de una consulta, y más aún ese es el único bit de datos que
quieres devolver. ¿Todo bien? Por lo tanto, desea
tener un objeto personalizado con solo bits de datos de todo
el conjunto de datos que se devuelven, y eso es todo lo que realmente
desea gravarlo en su sistema. Así que vamos a repasar
algunos ejemplos de, ya
sabes, cuándo
probablemente necesitarías hacer
algo como esto. Bien, te voy a
mostrar tres escenarios
en los que necesitas
saber manejar una selección. El primero es cuando
queremos seleccionar una propiedad. Como dijimos, tal vez, estamos consultando a toda la mesa del equipo Entonces digamos equipos. Y ya sea un
equipo o muchos equipos, el principio
seguiría siendo bastante el mismo, donde tenemos que decir contexto, punto y conseguir los equipos. Y luego trabajemos con
una lista en esta situación, bien, que por supuesto
tenemos que esperar. No, no quiero que todo
salga del equipo, porque sabemos que lo que
vamos a conseguir es una lista de objetos
con nombre, ID de liga. Y entonces si incluimos, entonces las otras cosas, ¿no? No quiero todo eso. ¿Y si todo lo que quería
fueran los nombres? Yo solo quería la lista de nombres. No quería ningún objeto
complejo ni nada más, ¿verdad? Entonces en ese escenario, lo que tendría que
hacer es agregar un selecto. Entonces yo diría
contexto hacer equipos punto seleccionar Y luego cuando hago eso, puedo usar mi
expresión Lambda para especificar qué propiedad
me gustaría seleccionar. Entonces, si selecciono nombre y
luego ejecuto la lista de dos, entonces esta es solo una lista
de cadenas. Todo bien. Porque el nombre es una cadena, y dije que quiero la lista de
todos los nombres del equipo. Entonces me sale la lista
de tipo string. Y eso va para
casi cualquiera que tú hagas. Entonces, si quisiera todos los
ID de liga de la tabla de equipos, entonces estaría
obteniendo una lista de enteros k al desaparecer Ahí vamos. Una lista de enteros porque el
ID de liga es un número entero Y así es como
iría para cualquier cosa. Listado de entrenadores. Todo bien. Entonces así es como vas a
seleccionar una propiedad. Ahora bien, el escenario podría ser que no solo
quieras una propiedad. Desea múltiples propiedades, y más aún, probablemente
desee varias propiedades de varias tablas. Todo bien. Entonces, veamos la proyección
anónima. ¿Y si quisiera seleccionar todos los equipos y quería incluir a
todos los entrenadores? Y todo lo que realmente quería
regresar, sin embargo, era la lista de Bueno, yo lista que contiene el
nombre del equipo y el nombre del entrenador. Eso es todo lo que realmente quiero. Entonces sabemos por nuestra experiencia
previa con las inclusiones que
terminaría haciendo algo como esto, déjame decir dot include. Y luego voy a decir,
asegúrate de darme los detalles del entrenador o el objeto entrenador
junto con el equipo. Pero luego quiero
seleccionar varias cosas. No puedo separar esto. Esto no funciona.
No puedo decir q punto. Entonces sabemos en SQL cuando
quieres columnas específicas. Todo lo que tienes que hacer es
decir columna, columna uno, ven columna dos, etcétera,
etcétera, todo antes de la fm Esa no es realmente
una opción aquí. Entonces por eso hablamos proyección a
otro tipo de datos. Entonces sobre la marcha, lo que se te permite
hacer es algo así como nuevo, y luego puedes abrir un objeto completamente nuevo directamente
en esa declaración select. Todo bien. Y entonces si
pasas el cursor sobre él aquí, dice que es de tipo anónimo Sabemos que C sharp está
fuertemente mecanografiado, ¿verdad? Entonces todo en C Sharp
está fuertemente mecanografiado. O es cadena, es
un int o algo así. Pero en esta situación, solo
estoy diciendo nuevo, no
hay nada
después de lo nuevo que decir
un sabía qué, ¿verdad? Entonces es solo un nuevo espacio en blanco. Pero luego
fíjense que no hay errores, y se le está
asignando un tipo anónimo Entonces no sabe
qué tipo de datos es. Simplemente sabe que es algún
tipo que quiero definir, y tiene una propiedad de
tipo string llamada name. Entonces ya está heredando
el nombre dado. Por el campo. Entonces en esta situación, Q representa al equipo. Entonces, si quisiera ser específico, tendría
que decir que el
nombre del equipo es igual al nombre del punto Q. Y entonces si
vuelvo a colocarlo sobre él , ya ves que evolucionó Dice, Este tipo anónimo tiene una propiedad llamada nombre del equipo. Todo bien. Entonces, ¿y si
quisiera el nombre del entrenador también Entonces puedo venir o separarme
porque no esto es un objeto. Entonces déjame
romper esto en una nueva línea para que veas dónde
está pasando todo, dónde empieza
y termina todo. Todo bien. Así que aquí está nuestro nuevo objeto que se está
definiendo . Entonces tenemos a Lambda. Entonces estamos proyectando en
este nuevo tipo anónimo, y estamos definiendo sobre la meta, qué campo nombra tiene
y qué valores obtiene. Entonces el nombre del equipo recibe el nombre de que, y luego el nombre del entrenador, Y no te dejes intimidar por el hecho de que
lo que estás escribiendo no viene en inteligencia porque una vez más, estamos
haciendo esto sobre la marcha Y sólo va
a funcionar con nosotros, punto, y luego se puede decir
punto entrenador nombre punto. Entonces, va a
tener dos propiedades, nombre del
equipo y nombre del entrenador. Si coloco el cursor sobre los equipos, entonces solo ves una lista de
este
tipo de datos anónimos, ¿de acuerdo Y luego lo estamos
proyectando en una lista. Entonces después de esto,
puedo decir cuatro cada uno, y solo haré un cuatro cada uno
aquí para imprimirlos, por cada ítem de
la lista de equipos. Puedo consolar punto línea derecha. imprima el equipo y ponga el nombre del equipo del punto del
artículo, y solo haré un pastel como delimter y el nombre del entrenador
del punto del artículo Así que incluso después de esta
proyección y esta creación muy aleatoria y
espontánea de este objeto anónimo, podemos acceder fácilmente a las
propiedades que fueron definidas. Entonces si modifico su definición, entonces el ítem pierde de vista el nombre del equipo era
una propiedad, ¿verdad? Entonces supongo que eso es tan
flexible como C sharp se pone, y puede ser muy conveniente de hacer
a veces. ¿Todo bien? Ahora, hay un
estudio de caso para esto, y puede ser muy útil,
como acabo de decir, pero personalmente, prefiero tener una proyección
fuertemente mecanografiada, es
decir, siempre conozco
los tipos de objetos con los que estoy interactuando cada vez que
ejecuto una consulta Entonces, como dije, podría
haber un caso en el
que necesites un objeto personalizado, y esto es bueno para un escenario
sobre la marcha. Sin embargo, en un proyecto más grande, quieres tener un poco más de
control que solo tener estos nuevos objetos anónimos por
todas partes. Entonces lo que querrías hacer es tener una clase fuertemente mecanografiada, y lo que voy a hacer es que voy a crear una nueva
carpeta dentro del dominio No debería entrar
dentro del dominio, sino que solo trabajemos con él. Yo sólo lo llamaré modelos. Por derecho, probablemente querrás
crear un nuevo proyecto, pero este es un proyecto demo muy
pequeño. No voy a ir al Salvaje Oeste con una
serie de proyectos. Pero en un proyecto más grande,
no quieres tener esto en un espacio dedicado que no se mezcle
con tus objetos de dominio. Pero estoy llamando a los modelos porque realmente son
modelos de los datos. Entonces este es un modelo de
los datos de la base de datos, pero entonces lo que voy a
estar creando es un modelo de probablemente como datos personalizados
que sé que espero. Entonces digamos que un modelo sería una cla llamada
Detalle del equipo. ¿Todo bien? Así que el detalle del equipo va
a tener algunas propiedades. Digamos que el detalle del equipo tiene
el nombre del equipo. Va a tener
el nombre del entrenador, y va a
tener el nombre de la liga. Esos son tres puntos de
datos diferentes de los que jamás
podríamos obtener con solo ejecutar una consulta regular. Tendríamos que incluir
todo sobre el entrenador y tendríamos que incluir todo
sobre el nombre de la liga. Y entonces puede llegar a ser algo molesto en la
recepción cuando
tenemos que decir equipos de entrenador de equipo. Entonces quieres
tener solo un objeto donde todo esté ahí
solo para ti. Entonces por eso
lo llamo modelo. ¿Todo bien? Así podemos proyectar en
esta consulta fuertemente mecanografiada. Así que sólo voy a
copiar esta consulta inicial. Permítanme decir todo
el asunto. Y voy a sumar e
incluir para el equipo. Así que recuerda, es tu consulta, cualquier dato que
necesites, ve a buscarlo. Entonces necesito equipo lo siento,
el equipo de liga. Así que estamos mirando la tabla del
equipo y estamos recibiendo los
detalles del entrenador incluidos, y estamos obteniendo los detalles de la
liga incluidos. Y luego voy
a seleccionar en una nueva instancia de detalle del equipo. Entonces fuimos anónimos arriba, pero ahora sabemos de qué
se trata a continuación. El detalle del equipo tiene nombre. También tiene nombre de entrenador, y luego tiene nombre de liga. Voy a decir el nombre del punto de
la liga Q. Del bate, cuando
miramos lo que se está devolviendo, sabemos con certeza que estamos obteniendo objetos de
tipo detalle del equipo. Entonces no tenemos que
adivinar y deletrear y decir, qué tipo de datos
puedo esperar esta vez. O no tenemos que ir
necesariamente a la definición para ver
cuáles eran todos los campos
en el tipo anónimo en el momento
en que el desarrollador lo hizo porque cuando tenemos una clase
fuertemente mecanografiada, siempre
podemos simplemente
mirar esta definición de clase Y una vez que sabemos que estamos
obteniendo este tipo de datos, entonces solo sabemos
cómo trabajar con ellos desde el principio. Todo bien. Así que solo voy a cablear todos estos y luego
vamos a echar
un vistazo a las diferentes
declaraciones QO que se están ejecutando para cada uno y qué datos
están regresando Todo bien. Entonces mirando
en nuestra consola, solo
podemos
pasar por esto lentamente. Nuestro primer comando, que
fue seleccionar una propiedad. Vemos que se trata de decir
seleccionar el nombre T del equipo. ¿Todo bien? Sencillo. Quieres una propiedad
o una columna. Así es como se
hace. No hay problema. En la siguiente,
dijimos que queríamos nombre y el nombre del equipo
y el nombre del entrenador. Todo lo que hicimos fue decir, seleccionar en este tipo anónimo, y especificamos las
columnas que queríamos. FCR generó exactamente
la declaración que necesitaba para obtener
exactamente esos datos Entonces seleccionó t
name como nombre de equipo, cual es el alias, ¿verdad? Entonces llamamos al
nombre del campo de manera diferente dentro de nuestro tipo o anónimo. Bueno, le dio el alias a
la columna dentro del SQL, y luego se deja
unir en consecuencia. Ya estamos familiarizados con
el include. Así que realmente solo estoy señalando la focalización de las
columnas que queremos. Y entonces estos son los
equipos que regresaron. Vemos que Juventos tiene Conte, Roma tiene a Joseph Marina, y todos los demás están en blanco.
Eso está bien. Ahora bien, para el siguiente con una proyección
fuertemente mecanografiada, es más o menos lo mismo Estamos seleccionando nombre T, nombre C como nombre de entrenador, y lideramos ese nombre
como nombre de liga. Entonces fíjate que dije
nombre, nombre, ¿verdad? Entonces no tuvo que darle
un alias
a este porque ese ya es
el nombre de la columna. Entonces el SQL no
le dio un alias, pero luego el alias estaba en
su lugar para los otros dos, y luego siguió adelante
e hizo las articulaciones. Y luego cuando lo imprimimos, vemos el nombre del equipo, entrenador y Siria, Siria, y estamos viendo todos los detalles de
la liga. Entonces aquí estamos apuntando a
las columnas que queremos. Entonces va a ser una consulta
mucho más pequeña, una carga útil mucho más pequeña que
solo conseguir que cada equipo y cada detalle de cada inclusión solo
traiga de vuelta una vez. Sólo va a decir, cuáles son los campos que estoy seleccionando o que
me interesan. Déjame cogerlos y luego
traerlos de vuelta como lista. Entonces una vez más, si bien
esta es una buena instalación, en un proyecto, sobre todo cuando
estás trabajando con otros, recomendaría que te apegues a los modelos fuertemente mecanografiados Tal vez hagas un
modelo diferente por tipo de datos que te gustaría
mostrar en la página para que cuando ejecutes la consulta, la extraigas directamente
en ese modelo,
y esa página se
modele a partir de esos datos Y si necesitas
extenderlo simplemente tu modelo y extiende
tu consulta en consecuencia.
26. Filtering en registros relacionados: Bien, chicos, así que estamos de vuelta, y estamos
viendo otro tema, y esta va a ser una lección
bastante corta donde
vamos a estar hablando de
filtrar con datos relacionados Ahora bien, ¿cuál es un escenario para
filtrar con datos relacionados? Tengo una consulta aquí, y
mi nombre de variable es incorrecto, así que déjame corregirlo a ligas. Y voy a consultar
la tabla de ligas, pero estoy consultando
la tabla de la liga sobre algo que pueda tener
el equipo Entonces piensa en un escenario donde
estés mostrando las ligas, estás mostrando al usuario
la lista de ligas, pero luego le permites
filtrar en función del nombre del equipo. Entonces sé el nombre del equipo
o parte del nombre de un equipo, y quiero ver en qué
liga está este equipo. Entonces eso significa que cuando
hago clic en enviar, debes ir y conseguirme la
lista de ligas donde
podría haber algún equipo que tenga un nombre que contenga
cualquier término de búsqueda. Así que imagina que este era un término de búsqueda proveniente
del usuario, por abreviación para Barn Munich, tal vez. Y entonces estamos diciendo aquí. Así que déjame tomarme el tiempo para reescribir esta consulta
solo para que no
parezca tan intimidante como probablemente
lo hace Ahora, lo decimos contexto
punto piernas donde. Todos estamos familiarizados con eso. Sabemos que tenemos
la expresión Lambda. Y entonces voy a decir donde alguna propiedad cumple
algún criterio. En este caso, el
criterio está en contra la propiedad de navegación,
que es equipos. Entonces voy a decir
equipos Q punto Y luego es una lista. Así que no puedo muy bien decir a los equipos ese nombre. Es
una lista de equipos. Entonces voy a usar cualquiera porque
cualquiera devuelve un booleano
basado en alguna condición Entonces voy a decir porque ya
estoy dentro de
una expresión Lambda, no
puedo volver a usar el
mismo token Lambda. Entonces Q aquí ya está
amarrada representando un récord de liga. Entonces no puedo usar Q en la otra vez. Entonces por eso tengo la X. Podría ser S. Una vez más, la expresión Lambda, la
ficha realmente no importa, pero solo te estoy mostrando por qué
tengo X en una y Q en la otra porque esta es un subconjunto de la expresión Lambda más grande. Entonces x punto y luego no puedo acceder a las
propiedades de la tabla del equipo. Entonces voy a decir
donde el nombre, y luego sabemos que el
punto ya contiene, y luego el término de búsqueda, y luego tenemos nuestra sentencia
ejecutora. Entonces eso es realmente todo lo que
hay que consultar contra registros relacionados, ¿verdad? Entonces, una vez más, los equipos
no es la mesa principal.
Esta es la mesa principal. Sin embargo, la operación
requiere que vayamos
a la mesa infantil para que
coincidan con alguna condición. Entonces, si miramos esto, nuestra declaración SQL que se genera sólo nos va
a dar la liga en para donde existe y
solo va a intentar seleccionar el equipo en función
del término de búsqueda o en base al criterio
que hemos especificado. Y entonces eso
nos devolvería una liga,
que, si no me equivoco, sería Bundes Llega.
27. Añadir vistas y otros objetos de datos: Ustedes son bienvenidos de
nuevo en esta lección, veremos cómo
podemos agregar objetos SQL que
no son tablas a nuestra base de datos a
través de migraciones Ahora bien, un estudio de caso para esto, hemos estado usando migraciones
hasta este punto para controlar la mayor parte de lo que
sucede en nuestra base No necesariamente querríamos
tener dos operaciones separadas, una en la que vamos
a escribir manualmente en las revisiones y otra donde estemos scripting
en las tablas Entonces sería bueno que solo
tuviéramos un centro, como punto focal a nuestra base de datos para que
siempre podamos retroceder y saber que todo lo que se hizo en la migración anterior se puede deshacer a través de este procedimiento en
particular Recuerda que
las migraciones actúan como un control fuente
para tu base de datos Entonces en esta
lección en particular
veremos cómo
podemos agregar una función, cómo podemos agregar una Y
luego por extensión, la misma técnica
que vamos a
usar para hacer todo esto se aplicaría a los procedimientos
almacenados y a cada tipo de función. No voy a entrar en los detalles de cuáles son
los guiones. En este punto, estoy
asumiendo que
ya estás familiarizado con
qué es la función, la función escalar versus
la función de valor de tabla, así
como cómo se construyen nuestras
vistas Así que solo voy a
centrarme en cómo metemos este Qule en la migración y por extensión
a nuestra base Ahora, como con cualquier viaje a cualquier
cosa con la base de datos, comienza con nosotros
agregando una migración. Entonces vamos a venir a nuestra
consola de administrador de paquetes, agregar una migración, y luego solo voy
a llamarlo agregando vista de detalles
del equipo y función de coincidencia
temprana. Como siempre digo, quieres
ser claro con tus mensajes de
migración. No seas vago en absoluto. Entonces solo voy a seguir adelante
agregar esa migración. No, no he hecho ningún
cambio en nada con ninguno de los elementos
relacionados con la base de datos. No he cambiado el contexto. No he cambiado
ninguna de las clases. Entonces se nota que estos van a estar vacíos
porque hice una migración. Yo no dije nada que
hacer y no decía
nada que deshacer. Entonces tenemos que poner manualmente
el código para que sepa qué
hacer para el up y qué
hacer para el dom. Entonces veamos
agregar la función. Entonces voy a conseguir
que las funciones SQL. Y voy a decir constructor de
migración. Entonces, lo que realmente hubiera
pasado es que
entré en SQL e hice esto. Entré en el Estudio
de Gestión, hice la función
manualmente. Eso está bien. Pero como dije, no
quiero
agregarlo ahí porque
quiero un punto de
entrada a todas las modificaciones
basadas en bases de datos en el
futuro, ¿verdad? Entonces voy a decir constructor de
migración punto, y luego puedo decir SQL. Lo que va a tomar un
parámetro de tipo string. Entonces está esperando
el comando cual como cadena tipo ahí mismo. Entonces lo que voy a
hacer es usar mi signo a para convertir esta cadena
en una cadena literal, y luego simplemente pego esa declaración
qual justo ahí Entonces así es como va a verse eso
. Así que el constructor de migración Q y
luego se pasa en cualquier Q. Así que aunque es Q para
crear una función. Es Q crear una vista como estamos a punto de hacer o
un procedimiento almacenado, sea lo que sea, eso es todo lo que realmente
necesitas hacer. Entonces sólo voy a copiar eso, y voy a repetir
ese paso con la vista. Entonces, en esta migración en particular, espero crear esa
función y crear esta vista. Ahora, sí lo dije y lo
dije desde antes, así que deberíamos estar familiarizados
con el hecho de que el up significa el cambio que
estoy a punto de hacer. El abajo significa los
cambios que deshago o las cosas que hago cada vez que
se está retrocediendo esta migración. Entonces, si tengo las
declaraciones create dentro del up, eso significa que necesito poner las declaraciones
drop dentro del down. Así que solo voy a hacer ese
constructor de migración punto SQL drop view, y luego le doy
el nombre y luego soltar función con ese nombre. Entonces esta es la primera
vez que tenemos nuestras manos, ya
sabes, suciedad aquí dentro
de los archivos de migración. Sigamos adelante y hagamos una base de datos de actualización y
veamos cómo sucede la magia. Y mi experiencia no fue muy mágica porque tengo un error. Y como lo estoy viendo, veo que tengo un error en esa línea. Entonces
déjame corregirlo. Me había vuelto demasiado celoso y
repitió la palabra coincidencias. Entonces intentemos eso otra vez. Probablemente lo
detectaste y no obtuviste ese error
que es perfecto. Y en ese punto,
todo está hecho. Y si miramos en nuestra base de datos muy rápido
y miramos nuestras vistas, entonces verás la vista
que aparece ahí así como sobre la programabilidad
y funciones
y las funciones escalares
ahí tenemos nuestra
función ahí tenemos nuestra Entonces esta migración fue todo un éxito. Ahora, cuando
regresemos, vamos a revisar cómo podemos interactuar con una vista. Más adelante veremos cómo
interactuamos con funciones y otras operaciones escalares donde hacemos una llamada y esperamos
datos, pero luego con una vista, no
es realmente un
comando, estamos consultando, y va a ser
ligeramente diferente de cómo consultamos nuestras tablas, y hay ciertas reglas
que tenemos que conocer Entonces, cuando
volvamos, veremos
las modificaciones
necesarias para ello.
28. Querir entidades sin claves (como vistas): Oigan, chicos, bienvenidos de
nuevo. En esta lección, vamos a estar
construyendo sobre lo que hicimos en nuestro episodio anterior
donde creamos dos objetos no qual de mesa en forma de
función y vista Entonces vamos a seguir
interactuando con la
vista porque una vista en términos prácticos
es realmente como una tabla de solo lectura
desde el lado qual Entonces eso significa que nos gustaría que
nuestra aplicación
pudiera consultar esas vistas de manera similar a cómo
podemos consultar tablas regulares. Entonces lo que vamos a
tener que hacer es crear una nueva clase de datos
que corresponda con la vista y
agregarla al conjunto de bases de datos. Entonces ya he hecho esto donde creé
una nueva clase. Lo puse en el proyecto de dominio. Yo lo llamo equipos,
entrenadores, ligas, y acabo de anexar la
palabra vista para que sepas, a primera vista, podemos decir, esta es una vista
frente a las otras. Cualquiera que sea el prefijo postfix,
eso depende de usted. No estoy siendo prescriptivo. Sólo digo que
esta es mi convención para conocer las tablas diferentes
a las vistas. ¿Todo bien? También podría crear
una carpeta completamente nueva y poner en una vista de llamarlo, lo siento, y poner todos los modelos relacionados con la
vista allí. Sin embargo,
quieres separarlos, eso depende
completamente de ti siempre y cuando
sea limpio y
fácilmente identificable. Ahora, después de crear
esa clase para representar la vista y los
datos que se remontan a la vista, lo que queremos hacer es dejar que el contexto DB sepa
sobre esta vista. Así que voy a
agregar una nueva línea en este contexto DB donde
voy a decir conjunto de base de datos, darle el tipo de datos, y voy a llamarlo simplemente el mismo nombre que la
vista en la base de datos. En nuestro programa punto CS, vamos a seguir el ejemplo con lo que hemos estado
haciendo hasta ahora, y acabo de crear una revisión de consulta de
método, que solo va a
tener el único propósito de llamar contexto, los equipos, entrenadores, ligas, y ponerlo a la lista. Sin embargo, vamos a ver
si realmente vamos a recuperar resultados y si vamos a obtener
algún error en el camino. Así que vamos a dar una vuelta a esto. Ahora, en cuanto
golpea el código, me saludan con esta excepción, y es decir que el tipo de entidad requiere de una
clave primaria para ser definida Si pretendiste usar
un tipo de entidad sin llave, tienes que explícitamente debes
hacerle saber explícitamente, lo
siento, que
no tiene clave, ¿verdad Entonces eso se espera, y ese es un error que
quería que viéramos juntos, porque a veces ese error te
ciega, y no estás del todo seguro de por qué estás
recibiendo ese error Entonces FCR, como hemos visto prospera
de integridad relacional. Las claves primarias se
definen como claves primarias, las claves
externas se
definen como claves externas. Y con eso, sabe
exactamente cómo hacer las consultas de manera eficiente,
cómo rastrear, si algo se está cambiando, y cómo simplemente
monitorear todo lo que sucede en el contexto
durante nuestra solicitud. Entonces por ese estándar, nuestra nueva tabla o
nueva entidad más bien. No sabe si es una mesa. No sabe si es una vista porque la agregamos
al contexto DB, al igual que como agregamos
todas las demás tablas. Entonces, en lo que respecta al
marco de entidades, lo va a tratar
como si fuera una mesa. No obstante, esa
excepción decía, no
veo una llave en esta mesa. No podemos ponerle una llave.
No es una mesa. Es una vista, y sí,
no tiene clave primaria. Entonces la excepción de que
en el constructor de modelos, tenemos que hacerle saber
que no tiene clave. Entonces tengo que decir
constructor de modelos entidad punto con el tipo de datos, y luego solo
especificamos no tiene clave. Entonces cuando se está creando
sabe que, bien, estoy consciente de que no
debería intentar rastrear esto. Si encuentro una mesa o
algo que coincida con esto, entonces sé exactamente qué hacer. Ahora bien, otra cosa que
nos gustaría hacer en este punto es decir dos vistas y dos vistas básicamente nos permite especificar el nombre de la vista en la base de datos
que debe buscar. Entonces esto es como una precaución
extra para asegurarse de que
no vea nada de
esto como ningún elemento nuevo o sujeto de
autos o nuevo trabajo, tiene
que hacer la próxima
vez que hagamos una migración Yo solo lo sabré, Bien, bueno, este tipo de datos, este tipo de clase, o este modelo se mapea directamente a la vista en nuestra
base de datos por ese nombre. Y no tiene llave, así que no hagas ningún seguimiento. Entonces lo que voy a hacer es
ejecutar eso un poco de código, otra vez, y voy a
dejar ese punto de quiebre para que
podamos ver lo que está pasando
en el rastreador de cambios. Por lo que esta vez llega
al punto de ruptura. Cuando miramos en detalle, veríamos que estamos
recuperando detalles porque la vista se está
ejecutando correctamente, y estamos recuperando entrenador, estamos obteniendo la
liga, y estamos obteniendo el nombre como esperamos. Y entonces el contexto
realmente no sabe nada de nada
que rastrear, ¿verdad? En lo que a él respecta, hizo su trabajo y está hecho, y sigue adelante con la vida. Entonces así es como manejamos
situaciones en las que no hay una clave primaria
presente porque
podrías terminar con una tabla sin una clave primaria
o un elemento ID como ese. Quizás te
veas obligado a lidiar con una base de datos heredada donde esas cosas no
se están haciendo cumplir, como la forma en que te estamos animando a hacerlas cumplir
cuando estás usando entity framework
core desde cero, porque esas
situaciones pueden existir. Pero entonces cuando se
tiene eso no tiene clave, batalla por luchar, entonces
este es el remedio. Lo pones en el constructor de modelos tan pronto
como pueda encontrar un contexto, lo
pones en el constructor de modelos, saber que no tiene clave, y luego puedes mapear directamente a la vista, o si es una tabla, en realidad
podrías decir punto a
tabla y especificar el nombre. Así que puede haber momentos en los
que tenga un desajuste entre el nombre de
la tabla dado en el contexto DB y la tabla real, siempre se
puede decir a la tabla
y luego darle ese nombre, igual que hicimos para ver. Bien.
29. Querir con Raw SQL: Oigan, chicos, bienvenidos de
nuevo en esta lección. Estaremos viendo cómo podemos
ejecutar consultas usando SQL sin procesar. Ahora, hasta ahora, hemos estado escribiendo
todo usando nuestro enlace, sintaxis y nuestro C sharp y todo
eso ha sido perfecto. Pero
podría haber una situación en la que necesites
escribir algo de QL sin procesar, y sobre todo ahora
que estamos tratando con objetos no relacionados con tablas, y empezamos a ver
que se vuelve un poco más complicado Ya sabes, ¿cómo ejecutas ese procedimiento almacenado
o esa función? ¿Cómo hacemos esto exactamente, pero manteniendo todo el uso
del núcleo del framework de entidades Entonces aquí vamos a
ver dos ejemplos a medida que
avanzamos a través de estos
diferentes escenarios. Ahora, tenemos dos
funciones que
nos permiten ejecutar comandos de cual raw, y eso es de Q R y
de Q interpolado Ahora bien, anote la sintaxis, es contexto hacer equipos. Entonces todavía tenemos que
especificar nuestra tabla, y luego decimos desde QL R, entonces podemos poner en nuestra declaración de cual raw
y luego a listar Ahora bien, debo señalar algunas
de las limitaciones aquí y los peligros asociados
con este QL crudo Una vez que estés usando
esta función, realmente
te abres
al potencial de la inyección SQL si no estás siendo
muy cuidadoso. Entonces por eso te
dieron desde QL raw y desde SQL
interpolado, Entonces veremos la diferencia
en unos momentos. Entonces veamos con qué
volvemos de Q R. Solo comento el que aún
no estamos usando. Y desde SQL raw, tenemos que decir algo así
como seleccionar estrella de equipos tipo de
contador intuitivo, ¿verdad? Acabamos de decir contexto hacer equipos, y después tengo que decir seleccionar
estrella de los equipos otra vez. Pero veamos qué
recuperamos cuando probemos esto. Ahora cuando revisamos nuestros resultados, vemos que sí
recuperamos la lista de equipos y estamos
recuperando cada cosa. Nosotros dijimos estrella selecta, así que los estamos recuperando
y todo está bien. Ahora lo que pasa con el
SQL sin procesar es que tiene que devolver columnas que coincidan exactamente el conjunto de bases de datos o con la entidad
detrás del conjunto de bases de datos. Entonces en otras palabras, si solo
quería pero los nombres de
los equipos y dije, seleccione nombre de los equipos,
déjeme mantenerlo sencillo. ID no es sencillo. Déjame usar ID nombre común. Sólo quiero dos columnas
de la tabla de equipos. Si intento eso,
entonces terminamos con esta excepción diciendo
que hay ciertas columnas no
representadas en el
conjunto de consultas porque intentó consultar solo dos columnas,
pero está esperando. Entonces esa es una de las limitaciones con este comando SQL sin procesar. Entonces, el número uno, la
consulta o el
conjunto de resultados deben devolver todas las
propiedades del tipo de entidad. Otra cosa es que los nombres de las
columnas deben coincidir. Entonces, aunque tuviera que enumerar
todos los nombres de las columnas, no
puedo darles alias
que no se mapean
al tipo de entidad original
en nuestra clase llamada team Y entonces otra cosa es
que no podemos inter unirnos, no
podemos
tener directamente datos relacionados. No obstante, puedo, en este
punto, decir, incluir Bien. Entonces después
de escribir el SQL crudo, todavía
puedo hacer mis declaraciones
include, y funcionaría
igual que cómo sabemos que funcionará
independientemente, ¿verdad? Entonces, si hago eso e
incluyo al entrenador, entonces veremos por nuestros equipos, y creo que el equipo
número tres tiene un entrenador y ahí vamos, veremos que la entidad entrenador está incluida en la
forma de Joseph Moreno. Todo bien. Entonces esa es una de
las cosas que puedes hacer. Si alguna vez necesita
ejecutar esto desde EQ raw y necesita datos relacionados, solo sepa que puede
incluir de la misma manera. Ahora, ya estás familiarizado
con SQL en este momento. Entonces ya sabes que si quisiéramos
agregar un filtro, por ejemplo, si quería encontrar
el club de fútbol
donde el nombre es igual
a esta variable, y lo hemos hecho en el pasado
donde realmente aceptamos la entrada del
usuario y luego usamos esa entrada de usuario para
el filtro, ¿verdad? Entonces digamos
que queremos usar esta variable para nuestro filtrado. Siempre podemos simplemente decir, donde nombre es igual a, y luego pasamos
en nuestra variable. Entonces, la interpolación
nos haría poner este signo de dólar
antes de la cadena, y luego podemos simplemente
hacer nuestras llaves y luego poner el
nombre en esa área Ahora bien, si echamos un vistazo a la QL que se
genera para eso, veremos cuál
no necesariamente
miramos las dos últimas veces que está generando
nuestra sentencia SQL, y está haciendo la unión izquierda automáticamente debido a
los includes Pero entonces toma nota de esto ahora. Lo que estamos haciendo
aquí es pasar estrella
selecta de equipos
donde el nombre es igual a. Y fíjense que está
pasando en el valor, pero no lo
está pasando entre comillas, porque en SQL, habríamos
tenido que poner donde
nombre es igual a. Abrir tal vez solo el valor y cerrar comilla simple cuando
estamos tratando con una cadena. En consecuencia, se queja que no puede encontrar
la palabra clave
ya que A S roma está siendo
vista como comando AS en ques Entonces para remediarlo, en nuestra
cadena interpolada tenemos que poner nuestras comillas
simples
alrededor de los valores Entonces intentemos eso otra vez. Y esta vez estamos
golpeando nuestros puntos de quiebre. Nuestra consulta fue exitosa. Pero una vez más, si nos fijamos en esta consulta comparada con consultas
anteriores donde
hicimos filtrado, nota
que no
hay parámetros. Se trata de pasar el valor literal
directamente a la consulta, A K una mala práctica, inyección
QL. ¿Todo bien? Entonces, si alguna vez tienes que
terminar tomando algún parámetro y usando un comando QL sin procesar
para ejecutarlo,
entonces esto es lo que va a pasar, y hay que tener mucho
cuidado porque si alguien pasa algún
comando malicioso como entrada,
entonces habrías vuelto al
cuadrado uno antes de los días en entonces habrías vuelto que se
desarrolló ese framework de
entidad para
ayudarte a prevenir la desarrolló ese framework de
entidad para
ayudarte a inyección de Qual En una situación como
empleamos los servicios de su primo cercano de
qual interpolado Si nos fijamos en este, es pedir una cadena formable De qual solo está
pidiendo una cadena, pero luego desde sc interpolada está
pidiendo una cadena formable, lo
que significa que solo
aceptará una Y dos, no tenemos que tratar esta declaración del auto como literal como lo hicimos hace un momento porque la
va a interpolar Entonces automáticamente
va a manejar la parametrización
del comando, así que no tenemos que poner en
las capas individuales alrededor del
interpolado o el valor inyectado en la Entonces echemos un vistazo a
esa qual y comparémoslos. Entonces ya ves,
miramos éste hace un momento, donde pasó en
el valor literal. Mientras que el segundo en realidad
va a decir seleccionar estrella de equipos donde nombre es igual
al parámetro cero, y ha definido
el parámetro arriba. Y esa es la
diferencia entre de
raw de scle raw y
de escule Por lo que siempre recomendaría
que si tienes que mezclar y combinar con variables para pasar en una declaración de cual crudo, usa la qua interpolada para tu propia protección
y tranquilidad
30. Añadir y consultar con los procedimientos almacenados: Oigan, chicos, bienvenidos de
nuevo. En esta lección, vamos a echar un
vistazo a la interacción con los procedimientos almacenados utilizando el núcleo de marco de
entidad. Ahora, el estudio de caso de
por qué
necesitarías interactuar con un procedimiento
almacenado
proviene del hecho de que
tal vez estés tratando con sistemas heredados donde gran parte de la lógica está en
procedimientos almacenados en la base de datos. Entonces en la reconstrucción, no
quieres duplicar el trabajo, reescribirlos,
solo reutilizarlos. Entonces en esa situación, probablemente solo necesites
saber cómo hacer
llamadas de procedimiento almacenadas desde FCR Entonces tengo uno muy simple que he construido para
el contexto o
base de datos donde solo
tengo entrenador de equipo SPG, y obtiene una identificación de equipo, y luego regresa de
todo de la mesa del entrenador Ahora recuerda que cuando estamos
tratando con RwQul tenemos devolver todo lo que corresponda con el tipo de entidad
coincidente Bien, así que no
puedes simplemente decir el nombre. Tienes que hacerlo si
vas a enumerarlos,
tienes que enumerarlos en el orden de los
nombres de las columnas con
los mismos nombres de columna, sin Ss y nada. Entonces, como hicimos con nuestros
puntos de vista y funciones, lo primero que
vamos a hacer es crear una nueva migración. Agregué una migración diciendo que
agregó el nombre del entrenador SPG. Yo estropeé el nombre de la migración,
pero continuaremos Y luego puse en el constructor de
migración para crear el procedimiento y de manera similar
para caer después. Para que puedas seguir adelante y hacer la migración y
hacer esos pasos, y luego solo podemos
actualizar nuestra base de datos. Y entonces eso nos permite comenzar a interactuar con nuestro procedimiento
almacenado. Ahora, en nuestro programa CS archivo. Ya he seguido adelante y
escribí algún código de muestra, y el nuevo método
con el
que estamos trabajando es el procedimiento almacenado. Entonces en el procedimiento de la tienda, solo
codificé duro un ID de equipo, y luego lo voy
a pasar a la instrucción SQL sin procesar
y esperar el resultado. Ahora, echemos un
vistazo a la sintaxis. Yo digo esperar contexto
punto entrenadores hacer fc R entonces llamo a mi ejecución
para conseguirme entrenador del equipo SPG, y luego tengo un marcador Ahora tenga en cuenta que estoy usando de squlRW En la lección anterior, dejé de
condenarlo diciendo que estaba mal porque te
abre para La realidad es que se
basa en cómo lo usas. Entonces te mostré la mala
manera de usarlo inicialmente donde usé una cadena
interpolada y pasé válida directamente en Entonces todo esto se
tradujo a QL literal, que es
lo peor que puedes tener
entre la entrada del usuario y
ir a la base parametrización es siempre la mejor, ahí nuestra preferencia
por lo interpolado Pero entonces demos un
paso atrás y no condenemos de SQL raw demasiado porque si echamos un
vistazo a su sobrecarga, realmente dice,
dame la cadena SQL y luego dame
una lista de parámetros Entonces eso es exactamente
lo que hemos hecho aquí. Digo DBO punto SP conseguir entrenador de equipo, y luego uso un marcador Y luego después de ese
marcador de posición después de esa cadena, ahora
he incluido
el parámetro Entonces, cuando lo hagas de esta manera,
en realidad manejará
la parametrización por ti de la misma
manera que vimos desde Equal Interpolateed Entonces no es el peor
método y no es completamente usess porque
probablemente dejaste la última
lección preguntándote Entonces, ¿por qué lo pusieron
si es tan peligroso? Hay una buena manera de
usarlo y hay una
mala manera de usarlo. Entonces, te mostré el mal camino. Aquí está la mejor o más
recomendada forma de usarlo. Entonces echemos un vistazo a eso. Ahora, cuando echamos un
vistazo a lo que
recuperamos, vemos que nuestra consulta se está generando
y parametrizando, como dijimos, o
esperábamos que Entonces ahí está tomando
ese parámetro de tres, ejecutando un procedimiento stird Y entonces nuestro resultado es la información de
Joseph Marina como entrenador
de equipo para
equipo con ID tres. Entonces así es como se puede
ejecutar un procedimiento almacenado. Y más o menos así es
como ejecutamos comandos contra una base de datos que
están bien, comandos de consulta. Estamos pidiendo algo a la base
de datos y
vemos que nos devuelven. Entonces en esa situación,
por eso tenemos que ejecutar estos comandos QL sin procesar
contra una tabla En cada situación. Ahora bien, lo que sucede cuando
necesitamos ejecutar un procedimiento almacenado
que no está
asociado a una tabla o consulta
es algo que no está directamente
asociado a ningún tipo de entidad. Entonces necesitamos QL crudo contra algún objeto que no esté
asociado con un tipo de entidad Eso es lo que
vamos a ver
en nuestra siguiente lección. Bien.
31. Ejecutar la aplicación de la consulta Raw SQL: Ustedes
volverán en esta lección, vamos a estar echando un
vistazo a cómo podemos ejecutar comandos que no son de consulta
contra la base de datos. Entonces un ejemplo de esto
sería cuando queremos eliminar o actualizar algo que manipula o
aumente los datos, pero no
necesariamente nos devuelve nada porque no
estamos seleccionando Así que hasta ahora, hemos estado seleccionando y seleccionando
y seleccionando. Veamos lo que hacemos
cuando no estamos seleccionando, pero tenemos que ejecutar
este tipo de comando. Tengo en pantalla un nuevo equipo de eliminación de
migración por IDP, SP abreviatura de procedimiento almacenado, y tengo el código para crear el procedimiento almacenado
llamado delete team by ID, que toma un
ID de equipo como parámetro, y luego elimina
al equipo Tenemos los
métodos arriba y abajo que puedo pausar, replicar esos, y luego
seguir adelante y actualizar los datos Ahora, después de haber completado
eso con éxito, puede dirigirse al
programa punto CS y verá ya creado el método
ejecutar comando non query. Ahora, cuando vamos a
ejecutar el comando non query, hay algunas cosas
que van a ser diferentes entre
esto y cuando sabemos que estamos esperando un
conjunto de resultados y estoy tratando de que aparezcan ambos conjuntos de código en la pantalla que podamos hacer un análisis
comparativo. Número uno, sólo nos van a decir cuántos roles se
han visto afectados. A diferencia de cuando
buscábamos a los equipos, sabíamos que estábamos
recuperando un resultado conjunto de equipos. En esta situación, sólo
vamos a recuperar alguna
variable que diga, número de filas afectadas. Todo bien. Entonces eso es todo
lo que estamos consiguiendo. Esa es una. Dos, cuando estábamos haciendo los otros donde sabíamos que
estábamos recuperando datos, sabíamos
contra qué tipo de entidad o conjunto de
bases de datos ejecutarlo porque no
esperarías estar consultando estrella
selecta de entrenadores
sino contextualizar ese equipo Sabemos que
solo obtendrías un error cuando intenta ejecutar ese
método por completo. No obstante, ante esta situación, como no sabemos
qué va a estar haciendo el
procedimiento almacenado , no
sabemos con qué mesa está interactuando
directamente. Decimos
base de datos de punto de contexto en lugar del nombre de conjunto de base de datos de punto de
contexto. Así que la base de datos de punto de contexto, y luego los métodos que
obtengamos van a ser
ligeramente diferentes. En el caso del conjunto DB, obtenemos de CLR y
de Q interpolado En esta situación,
obtenemos base de datos dot ejecutar SQL raw y tiene una versión
asíncrona a Entonces tenemos raw y
tenemos R A sync. De ahí el ingenio, donde
está en el Async. Y entonces de manera similar, tenemos ejecuta nuestro qual
interpolado Entonces tenemos la versión
interpolada y tenemos la versión raw Ahora, ya
exploramos el mal uso
del método crudo y
cuanto más aceptable, el uso más seguro del método crudo. Lo mismo se aplica aquí. No sabemos cuál es el
procedimiento almacenado que vamos a hacer, pero sí sabemos que necesitamos
pasar algún valor, que es más que
probable que vaya a venir de nuestro usuario. Así que queremos
protegernos y usar una cadena formateada
con un marcador de posición, no la
cadena interpolada cuando estamos usando la sincronización de ejecutar Q R A. Y luego, claro,
si no quieres esa
responsabilidad adicional de pensar tanto, no hay problema. Por eso
te dieron la alternativa para ti solo pasa en la cadena
interpolada, y hace lo mismo por ti Entonces echemos un vistazo a lo que
obtenemos cuando ejecutamos estos
métodos. Todo bien. Entonces estoy viendo la matanza
que se ha generado, y veo aquí se ha parametrizado con ID de equipo dos, y todo se
parece a lo que esperaba No obstante, me está diciendo
que falló. ¿Por qué falló? Eso es por esa restricción de clave
foránea que tengo en el registro. Por lo que tengo partidos
relacionados con equipo con ID dos. Para que pueda usar esa.
Esos son mis malos datos. Déjame intentarlo de nuevo. Bien, entonces estoy ajustando mis valores
porque solo quiero
buscar algunos equipos que
sé que no tienen ningún partido. Así que no deberíamos volver a tener ningún error de restricción de
clave externa . Déjame intentarlo de nuevo. Y esta vez llegamos al
punto de quiebre, que significa que todo se
ejecutó correctamente. Ahora bien, si miro los papeles
afectados LC, uno. Si miro aquí abajo, veo uno. Entonces solo te dice, que ejecutamos
esto exitosamente, y este es el número de
filas que se vieron afectadas. Entonces, si querías que dijera
alguna bandera, fue exitosa o no,
entonces siempre se podría decir, es el número de
filas afectadas mayor a una, entonces podemos decir que fue
exitosa. ¿Todo bien? Entonces eso
es realmente todo para ejecutar sentencias de comandos QL
sin consulta usando QL sin procesar. Bien.
32. Datos de Seeding: Oigan, chicos,
volveremos en esta lección. Vamos a echar
un vistazo rápido una de las carreteras menos transitadas, pero imprescindibles de conocer, que es cómo sembrar datos. Ahora bien, la siembra de datos, si
no estás tan familiarizado con
lo que estoy hablando, es el acto de poner datos en la base de datos
al principio Entonces, en cuanto tu
aplicación esté instalada, puede
haber datos predeterminados
que necesites ahí, tal vez como una lista de países o ciertos roles o
como un usuario predeterminado, cosas así,
probablemente solo quieras los del sistema en
el momento de la creación. Tan pronto como se cree la
base de datos, estas cosas deben estar ahí dentro. COR nos permite codificar
eso para que siempre que
nuestra base de datos se esté generando con este
script o estemos ejecutando la base de datos de actualización para que
la base de datos se ponga al día con
todas las migraciones, en realidad
podamos poner
en código que se
verá como una migración
para que cuando se ejecute esa
migración,
esos datos se pongan automáticamente
en la base de datos
desde el código get la base de datos se ponga al día con
todas las migraciones, realidad
podamos poner
en código que se
verá como una migración para que cuando se ejecute esa
migración, datos se pongan automáticamente . Entonces eso es lo que queremos echar un vistazo rápido en esta lección. Ahora, la forma más sencilla de realizar la siembra es
hacerlo desde el método de
creación de modelos Bajo todo esto, podemos
decir constructor de modelos punto, y luego especificamos una entidad. Digamos que tenemos equipos, tenemos ligas, tenemos
partidos, tenemos entrenadores. Digamos que quería sembrar
algunos entrenadores en el sistema. Voy a decir coach de entidad y ese entrenador de entidad tiene datos, y luego esto tiene
datos me permite especificar tantos
entrenadores como necesite. Eso no es ci brass
eso es paréntesis. Y luego entre estos paréntesis, ahora
comenzaría a
darle nuevos objetos coach Entonces puedo decir nuevo entrenador. Puedo especificar la
identificación desde el principio. Voy a usar unos ID que
sé que no chocarán con
los existentes. ID 20 nombre es igual a Voy a usar mi
nombre en esta situación. Y el ID del equipo. Bueno, puedo dejarlos como ll porque estoy sentando al entrenador. Ahora, eso trae otro punto
importante. Si tienes datos jerárquicos, entonces necesitas
asegurarte de que estás sentando según el orden o
el nivel de dependencia, la misma manera que queremos
crear las tablas con las dependencias de la
misma manera que necesitamos sembrar los datos con
esas Porque no puedo estar esperando
poner en Trevor Williams, el entrenador del Team ID five, pero luego estoy definiendo al equipo con ID cinco después de todo eso ¿Todo bien? Entonces déjame mostrar
exactamente a lo que me refiero. Si digo equipo,
quiero un nuevo equipo, voy a estar sembrando un nuevo equipo y este equipo va a
tener digamos ID 20 El nombre del equipo es Trevor Williams
Equipo de muestra. Todo bien. No puedo estar diciéndole a
este entrenador que su ID de equipo es ID 20
porque el orden en el que he definido estos comandos
semilla es el orden en
el que
se va a generar la declaración del auto . Así que no puedo estar creando
coach e insertando coach con ID de equipo 20 cuando el
equipo ID 20 aún no existe. Entonces tengo que
asegurarme de mantener
mi orden de acuerdo a
los niveles de dependencia. No, como dije, puedes
poner tantos como quieras. Entonces tengo un nuevo entrenador aquí, y luego puedo separar tantos objetos de
nuevo entrenador como necesite. Entonces si quería tres entrenadores
en el sistema inicialmente, claro, los ID pueden chocar. Entonces solo mantengamos ese nombre, muestreemos uno y muestreemos dos. Y luego para los equipos, bueno, no
puedo ser el entrenador del mismo equipo una
y otra vez. Porque conocemos las limitaciones. Entonces, cualesquiera que sean las restricciones que existan
en la base de datos, por supuesto, regirán y las limitaciones
que tengas cuando estés haciendo tus
asientos, ¿verdad? Solo quieres ser
consciente de todo eso. Por supuesto, una vez más, esto es probablemente cuando el
sistema se acaba de instalar. Entonces estoy usando IDs 2021, y 22 porque ya tengo equipos y entrenadores en el sistema.
No quiero chocar. Sin embargo, en un sistema completamente nuevo
y un paradigma completamente nuevo, probablemente
comenzarías con uno, dos, tres, cuatro como tus identificaciones porque
esas son las identificaciones en las que
definitivamente quieres entrar
antes que nada. Ahora, Si tuvieras que hacer
siembra para múltiples tablas, puedes ver que puede llegar bastante engorroso y Honestamente, no
me gusta ver todo
eso en el Eso es demasiado código. Quiero mantenerlo un poco más limpio. Entonces lo que hago o te recomendaría que
hagas en esa situación es extraer estos en clases de
configuración de semillas. Entonces lo que tiendo a hacer es crear una carpeta y la
voy a hacer en el proyecto de datos
cerca de las migraciones Entonces lo llamo configuraciones, y luego tengo otra Carpeta ahí
porque puede haber múltiples tipos de configuración
que podríamos querer hacer. A
eso le voy a llamar entidades. Y luego dentro de eso, voy a tener las diferentes clases de
configuración por tipo de entidad. Entonces, por ejemplo, quiero una configuración de CD de
coach. Ahora bien, en esta clase, que voy a hacer pública, voy a heredar de la configuración del tipo de
entidad Así que voy a seguir adelante
y agarrar esa referencia, y voy a decirle que
es para el entrenador tipo. Y luego incluir cualquier cosa
que falte. Entonces para el
entrenador tipo, quiero eso. Entonces ahora voy a tener que
implementar esta interfaz, lo que me da este método
configure y un constructor local. Entonces ahora que tengo este constructor,
este constructor básicamente se parece
al mismo propósito que este objeto constructor de
modelos, ¿verdad? Entonces solo puedo decir que tiene datos. Yo solo voy a tomar
esta parte como para equipo, permítanme simplemente tomar la parte de los datos que
tiene de ella. Voy a cortar voy a borrar todo esto
del contexto DV. Y luego por aquí,
quiero decir constructor, punto y luego poner tiene datos. Entonces todo lo que tenía tiene datos y más allá encaja
perfectamente en este método. Entonces Builder dot tiene datos, y luego puedes
poner tantos
registros de ver en esta clase dedicada. Ahora, por supuesto, si me estoy
mudando a una clase dedicada, necesito una manera de hacer referencia o hacer referencia
a ella en el contexto DB. Así que de vuelta en el contexto DB, voy a decir constructor de modelos
punto, aplicar configuración, y luego nuevo y simplemente pasar en el nombre de este
método o lo siento, esta nueva clase que creamos, que es una nueva clase de
configuración. Entonces solo paso en una
nueva instancia de esto, y eso es todo. Así que tantas
clases de configuración como
crees, solo necesitas
pasar en estas líneas. Una vez más, manteniendo
ese orden. Así que lo hice para asientos de entrenador
o autocar. Hagamos lo mismo
por los equipos, ¿no? Así que solo voy a
jugar un poco perezoso aquí y
solo copiar y pegar el archivo existente
y simplemente cambiar el nombre al
asiento del equipo, configuración. Y luego voy a actualizar
las referencias en el archivo. Entonces este es un
equipo de cuatro tipos. Esto es para equipo. Y entonces nuestra sección tiene datos va a
venir directamente de esto. Sólo voy a cortar y pegar en su archivo de
configuración dedicado. Y de vuelta en el contexto DV, puedo simplemente duplicar
esto y decir configuración semilla
del equipo,
y ahí vamos. Entonces eso me parece mucho
más limpio, y es tan
efectivo como tener
todo en el archivo. Pero claro, este
método se mantiene un poco más kosher y se ve un poco mejor
cuando lo hacemos así Entonces echemos un
vistazo a lo que obtenemos cuando
intentamos agregar una migración. Y cuando hago eso,
lo llamo agregaron
equipos y entrenadores predeterminados. Ahora estoy viendo que el constructor de
migración está haciendo
algo diferente. Nunca antes
lo habíamos visto hacer eso. Por lo que siempre es crear
tabla o alterar tabla. Ahora, es insertar datos en los equipos de mesa con estas
columnas con estos valores, y está haciendo eso
por todo. Y una vez más,
ese orden importa. A ver se encargó
de todos los equipos. Y entonces va a
encargarse de todos los entrenadores que tienen dependencias de
los equipos, ¿verdad Así que imagina si estos
estuvieran mezclados, estaremos tratando de
insertar un entrenador con
un ID de equipo 21 antes de que el equipo con ID 21 incluso se
creara receta para el desastre. Entonces solo recuerda que
el ordenar importa. Y en la D, los datos de
eliminación es simplemente revertir todas esas inserciones con esa sentencia delete. Entonces, si hago una actualización de base de datos, voy a obtener este
error, ¿de acuerdo? Estoy recibiendo este error
diciendo que tengo un conflicto con el equipo
y la columna de ID de liga. Todo bien. Eso está bien. Entonces en esa situación, tengo que modificar
lo que está pasando con el equipo porque
no completé los datos, así que hay que estar al tanto de eso. Hay que ser consciente
de que tus restricciones regirán si los datos pueden entrar o no Por lo que el ID de liga no puede ser nulo. Esa es una restricción
que está en la base de datos. Un equipo tiene que estar en una liga. Entonces no puedo estar
sentando equipos sin ligas. Entonces solo voy a
sembrar rápidamente una liga de muestra. Entonces siguiendo los mismos pasos, y
te voy a animar a hacer una pausa y
probarlo tú mismo. Pero lo que he hecho es
crear una nueva clase a la que estoy llamando configuración
semilla de liga, siguiendo los mismos
pasos heredando de la
configuración de tipo entidad de tipo league Y luego solo estamos construyendo una liga con el
ID 20, una vez más, para evitar cualquier choque
en la base de datos, y el nombre es liga de muestra Entonces retroactivamente
voy y actualizo configuración semilla de
mi equipo para agregar esa ID de liga a
cada uno de estos equipos, y por extensión, el contexto
DB donde
ahora tengo esa configuración
semilla de liga sucediendo antes que
todo lo demás Ahora, cometí un
error, ¿de acuerdo? Generé esta migración
cuando los datos estaban incompletos. Ahora vemos que
esta migración está fallando. ¿Cómo retrocedemos? Bueno, el primer paso es
eliminar la migración. Así que eso siempre eliminará
la migración más reciente. Y entonces sólo puedo seguir adelante
y volver a generarlo. Y esta vez, si
miramos, vemos que está creando primero
la liga, luego va a crear los
equipos y luego a los entrenadores. Así que vamos a darle otra puñalada
a la base de datos de actualización. Y después de niveles de tala
y siendo muy verbo, vemos hecho, y
ahora sabemos que tenemos estos datos Entonces, una vez más, esto
es ahora una migración. Por lo que se espera que suceda a
lo largo de la cadena desde la migración
inicial hasta la última migración que pueda tener
para su base de datos. Por lo tanto, puede haber
momentos en los que tenga que introducir diferentes búsquedas y diferentes
tablas en el camino, y necesite estos valores
como predeterminados desde el primer día Bueno, esto es perfecto para eso. Solo tienes que seguir adelante agregar
en las configuraciones, y luego puedes simplemente
ponerlas en el contexto DB. Entonces el constructor de modelos
sabrá que cuando esté haciendo mi compilación cuando esté
creando el modelo, necesito estar al tanto de estas
configuraciones para asientos.
33. Cómo hacer las migraciones en lástica: Oigan, chicos, bienvenidos de
nuevo en esta lección, vamos a echar un vistazo a
retroceder y gestionar
las migraciones en general Así que hemos hecho bastantes
actividades donde hemos realizado algunos
cambios en nuestra base de datos, y con cada cambio, hicimos una migración y luego
actualizamos la base de datos. Pero qué sucede cuando
haces una migración que
no quieres del todo
o en retrospectiva, quieres retroceder, hacer
un ajuste y rehacerla un ajuste y rehacerla Ahora, en este ejemplo, ya
hice una migración. Te voy a mostrar los cambios
que
hice para desencadenar esta migración. Cambié el objeto de dominio base para tener estos cuatro campos. Y estos campos se suelen
utilizar con fines de auditoría. Ya sabes, cuando
tienes personas ingresando datos en una base de datos, quieres saber cuándo fue
creada cuándo fue
modificada por última vez y creada por
quién y modificada por quién. Ahora normalmente querrías que
estos fueran un poco claros. Entonces deliberadamente
los nombro mal, solo para mostrarte como un
error que probablemente
justificaría una corrección o un rollback o
algo así Entonces en esta situación,
si solo miras
los nombres de las columnas, no
son realmente
muy cohesivos, ¿verdad Fecha de creación última modificación. Si solo estoy
mirando ese nombre, no
sé si esta
es la fecha de última modificación o esta es la última
modificación por quién. No sé si
esta modificación significa fecha de
modificación o persona
que la modificó. No lo sé.
Entiendes a lo que me refiero. Entonces estas son las cosas
que si, ya sabes, si eres obsesivo
con estos detalles, entonces estas cosas te
quedarán algo feas No obstante, el punto es que he hecho estos ajustes
al objeto de dominio base,
que, por supuesto,
está siendo heredado por todos los demás objetos de dominio. Entonces cuando generé
esa migración, que acabo de llamar campos de auditoría
agregados, puedes seguir adelante y hacerlo así, ya
sabes, puedes
trabajar a mi lado. Pero cuando hice eso, te diste
cuenta de que solo agregaba esas columnas a
cada tabla que existe. Sin embargo, arriba y abajo. Y luego seguí adelante y
actualicé la base de datos, que fue una operación
exitosa. Entonces, a partir de ahora, cada campo la base de datos tiene
estas columnas de auditoría. Ahora bien, ¿qué pasa cuando ya no
estoy satisfecho con esto? Entonces
ya hemos visto que cuando
generamos una migración y nos damos cuenta de que
tal vez haya un error con ella, siempre
podemos eliminar
la migración. Pero mira lo que sucede
cuando trato de eliminar el Y si voy
al comando y digo, eliminar migración, todo
construye y es exitoso. Pero luego me sale este
error diciendo que la migración con ese nombre ya se aplicó
a la base de datos. Revertirlo e inténtelo de nuevo, y si se ha aplicado
a otras bases de datos, considere revertir sus cambios Ya ves todo eso.
Es decir, esta migración
ya se ha aplicado. Por lo tanto, no puede simplemente eliminar la
migración porque eliminar migración en realidad elimina la referencia o el registro de este
archivo de migración de la carpeta Entonces es una
caja fuerte que dice, ya
he tomado nota de
este cambio a la base de datos. Entonces no puedo simplemente ir
y borrar esto
del historial sin que usted
modifique la base de datos. Entonces eso es lo que
estamos aquí para hacer para entender cómo
manejamos ese rollback. Y es un procedimiento bastante
sencillo. No sé, tal vez
esto un mensaje podría habernos dado
una pista más grande o una mejor pista de cómo
podríamos revertir la base de datos, pero hagamos eso juntos Entonces, revertir la
base de datos es realmente una
actividad de actualización de la base de datos, ¿verdad? Suena algo contradictorio, pero solo trabaja conmigo aquí Entonces, para revertir la base de datos a
un punto anterior en el tiempo, lo que tenemos que hacer es ejecutar nuestro
comando update database y realmente decirle a qué migración en el tiempo
queremos actualizar,
cuál si es en el pasado, realmente
es volver a cuál si es en el pasado, realmente
es volver Entonces quiero volver a la migración que
hice donde
agregué los equipos
y entrenadores predeterminados justo antes de agregar los campos de auditoría Así que simplemente voy a
duplicar el archivo muy lentamente, o bien
puedes decir renombrar, y solo voy a
copiar ese nombre de archivo. No necesito el CS. Solo necesito el nombre
porque este es el nombre
de la migración que realmente
se almacena,
ese subrayado de marca de tiempo y cualquier verborrea que pongas detrás de él Entonces en la consola del administrador de paquetes, voy a decir actualizar la base de datos de nuevo. Y luego solo
pasaré en nombre de
la migración entre
comillas y presionaré enter, Y luego se ve que en
realidad ha hecho lo que
estaba en el hecho. ¿Todo bien? Entonces de eso es de todo lo que hablamos cuando tienes el
up y tienes el do. Entonces los comandos que
ejecutaron hace un momento eran eliminar de
todo lo que había. Se está alterando y está
dejando caer la columna modificada. Si miras en la parte do,
bueno, el archivo de migración, lo siento, si miras en la parte hecha
de este archivo de migración, eso es todo lo que hace, le dice
que deje caer las columnas. Entonces ese es un
ejemplo práctico de lo que sucede, nosotros uno revertimos y dos cuando este down realmente se
llama a la acción,
en realidad deshace
todo lo que hizo el up Entonces ahora que hemos revertido o actualizado la base de datos
a una versión anterior, en realidad
puedo seguir adelante ahora y decir con seguridad eliminar migración Lo hará de
buena gana y sin dudas ni
reparos, y ahí vamos Se ha eliminado esa migración
previa. Sólo voy a hacer
ajustes a mi basado en objeto principal. Ahí vamos. He actualizado estos nombres de
columna para que sean un poco más descriptivos de lo que
va a haber en ellas. Crear una fecha, fecha de modificación, creado por, modificado por. Ahora después de hacer todo eso, solo
vamos a
agregar nuestra migración
nuevamente agregar la fecha que se siente la
auditoría. Bien. Y cuando eso esté hecho, solo
quiero que echemos un
vistazo a lo que sucede
con nuestra columna de fecha. Entonces estas son columnas de fecha y hora
y no son anulables. Lo que sucede es
que cuando tienes un
campo de fecha y hora nollable en la base de datos, o tiene que poner un valor Entonces por eso obtenemos ese valor
predeterminado en todas partes que
se va a agregar esta columna de fecha y hora, ¿verdad? Así que no podemos tener fecha
en un campo de fecha anulable. Entonces es poner en
esa fecha predeterminada, que en la base de datos, probablemente
verías
algunos 01010001 Es sólo una
fecha predeterminada, supongo, desde el principio
de los tiempos. Todo bien. Entonces con todo eso hecho, podemos seguir adelante y
actualizar nuestra base de datos. Y voy a ejecutar ese comando sin
especificar ninguna migración, y va a ser una operación
exitosa. Ahí vamos. Por lo que ahora, nuestra base de datos está equipada con a nivel muy básico
algunos campos de auditoría. Entonces, cuando
la gente está entrando, claro, ¿queremos saber cuándo
crearon ese disco? Cuándo fue modificada por última vez, y luego quién la creó
y quién la modificó por última vez.
34. Manipular las entradas antes de guardar cambios: Oigan, chicos, bienvenidos de
nuevo en esta lección. Estaremos viendo cómo podemos manipular las entradas
antes de guardar los cambios. Ahora bien, un poco de trasfondo de por qué querrías hacer
algo así, estaría viniendo tal vez
del hecho que acabamos de agregar
campos de auditoría para todas las tablas, ¿verdad? Así que acabamos de agregar todos
los campos de auditoría en el objeto de dominio base. Y evidentemente, esto es un poco más de trabajo por hacer porque hemos visto que cuando
estamos agregando datos, tenemos que formular
los objetos y luego agregarlos y agregarlos al contexto y
luego guardar los cambios Ahora, eso significa que cada vez alguien agrega un
equipo o una liga o un partido o un entrenador
o algo a la base de datos o lo modifica, estamos poniendo una
responsabilidad extra en nosotros mismos o nuestros
desarrolladores para decir, poner
siempre en la fecha de creación, siempre poniendo una fecha modificada, al
menos si quieres que los
datos sean estándar Ahora bien, hacer eso en
un sistema más grande puede llegar a ser muy engorroso porque solo
estamos trabajando
con cuatro mesas, y ya estoy molesto con
solo pensarlo Imagínese cuando tenga 2030
y más mesas tratando. Entonces, en este punto, es bueno entender
cómo el contexto realmente te
da acceso a todo lo
que está a punto de salvarse, y en realidad puedes
manipular lo que necesitas manipular antes
de guardar los cambios. Voy a pasar a
nuestro contexto de datos aquí, y va a ser una
experiencia bastante interesante ahora porque podemos anular los cambios de
guardado, ¿verdad? Entonces vemos bastantes opciones de guardar cambios
para ser anuladas Tenemos el predeterminado,
que es cuando llamamos
context dot save changes. Podemos anularlo. Y entonces podemos llevar
a cabo algunas operaciones aquí antes de decir
realmente guardar los cambios. Notarás aquí
que guardar cambios realmente devuelve un entero, que suele ser
más de uno cuando es un guardado exitoso y menos de uno o cero cuando no
fue exitoso. Entonces, si es necesario, probablemente
pueda incorporar
eso a sus cheques para ver si fue una operación de
guardado exitosa o no. Pero por ahora, no nos
vamos a centrar en que lo que queremos hacer es saber cómo
podemos interceptar todo lo
que está a punto de guardarse y manipular estos valores
antes de que se
guarden en la base Hay
bastantes cosas a tener cuenta cuando estás
en esta zona. En primer lugar, hay un objeto que se nos
ha dado llamado rastreador de
cambios. Creo que ya vimos
esto antes, pero vamos a ver
lo que nos permite hacer. Así que hemos cambiado de rastreador y luego podemos decir entradas de puntos. Esto realmente nos da
la lista de entradas que van a guardar los cambios
que están siendo rastreados por el
contexto en la memoria. Puedo decir que las entradas de VR son iguales a cambiar las entradas de puntos
del rastreador. Bien. Otra característica genial
de poder ver las entradas es
interrogar a lo que
llamamos el estado de la entidad Entonces esa es una enum que se nos ha dado. Una enumeración es solo una constante, y esta constante tiene diferentes
estados que generalmente representan en qué estado
estaría tu entrada para cuando
llegue a los cambios de guardado Así que no hemos cambiado. decir, tal vez hiciste una consulta, el rastreo estaba encendido,
así que lo está rastreando, pero luego no lo
actualizaste, no le hiciste nada, así que está en un estado sin cambios. Agregado, creo que eso se explica por
sí mismo. Estás a punto de agregar
algo a la base de datos. Así que cada vez que creas
un objeto y dices contexto dot add y
luego pones en el objeto, ahora
está en un estado agregado. Desapegado significa que no está siendo rastreado por el
contexto. ¿Todo bien? Modificado significa que
bueno, lo
tomaste, cambiaste algo en él, y luego dijiste, aquí está. Entonces, o bien estaba siendo
rastreado cuando se cambió. Entonces ahora, ve
que es diferente de lo que estaba
rastreando inicialmente, o no se estaba rastreando, y explícitamente llamaste context dot update
y la pasaste. Y luego en realidad hay
otra forma de actualizar donde
solo lo marcas como modificado, ¿verdad? Entonces en realidad puedes
simplemente ponerlo en el estado de entidad modificado para que el rastreador
lo sepa, debería estar rastreando esto
como un objeto modificado. Eliminado auto explicativo. Cada vez que decimos contexto
eliminar y darle el objeto, ahora
está en un estado eliminado. Entonces esos son realmente
los estados de entidad disponibles para nosotros, ¿verdad? Pero entonces en ciertas situaciones, es posible que necesitemos rastrear
algunos y no rastrear algunos. Entonces con las entradas, no
quiero ver
cada entrada. No necesito
nada que no haya sido modificado o que no
haya sido agregado, al
menos para mis fines de
auditoría. Ahora, una vez más, solo te
estoy dando un concepto de manta que probablemente
puedas adoptar por
diferentes razones, ¿verdad? Por lo tanto, es posible que tenga algún registro de auditoría
complejo o una segunda base de datos en la
que necesite escribir registros. Es posible que deba realizar un seguimiento, cuando se agregó esto. ¿Cuándo se modificó esto? Es esto se van a eliminar
y escribir eso un almacén de datos separado,
sea lo que sea, el rastreador de cambios le permite
interceptar estas entradas, hacer lo que necesite hacer todo antes de que se ejecuten los
cambios de guardado Entonces echemos un vistazo a eso. Lo que queremos hacer es obtener todas las entradas
que están a punto de ser modificadas o agregadas y luego
actualizar las columnas respectivas, ahora mismo, solo vamos
a centrarnos en las fechas. Bien. ¿Correcto? Y luego podemos seguir adelante y guardar los
cambios después. Entonces puedo extender este enumerable porque esta función solo está
devolviendo un enumerable, así que solo puedo extender
eso y decir dónde,
y podemos usar nuestra
expresión Lambda aquí mismo Entonces puedo decir donde Q o
mi expresión Lambda, y luego voy a
buscar el estado es igual a, y luego puedo usar
ese num para filtrar en agregado o Q es
equivalente al estado de entidad
que acabo de agregar, así que esto ahora se modificaría. Aquí mismo, estamos
filtrando y obteniendo todas las entradas que están a
punto de ser agregadas o modificadas. Bien. A continuación, voy a tener un cuatro cada lóbulo
pasando por estas entradas, y voy a
estar
convirtiéndolas en los objetos del dominio base Así que echa un vistazo a
lo que está pasando aquí. Entrada en entradas. Ahora bien, si nos fijamos en la entrada, entradas de tipo entidad
entrada. ¿Todo bien? Entonces cuando lo estoy convirtiendo, solo
puedo convertir entrada, pero tengo que convertir la entidad de punto de
entrada. Entonces entrada tiene algunos
objetos, algunas propiedades, puedes ver los
valores actuales en el objeto, puedes ver los valores originales. Entonces, incluso para fines de
registro de auditoría, puede ver dónde están las
propiedades antes o los valores en las
propiedades más bien antes y cuáles son
los valores ahora. Se puede mirar el contexto, y la entidad, por supuesto, encarna el tipo de entidad real del
que el contexto conoce Ahora bien, porque usamos
el objeto de dominio base y cada otro
tipo de entidad hereda de esto, puedo bajarlo a
este nivel para que pueda modificar los campos de objeto, porque en este
punto, no sé si estoy salvando un equipo de fútbol No sé si estoy
guardando un partido. No sé qué tipo de entidad realmente
viene
por encima en la entrada. Solo lo estoy lanzando
al objeto de dominio base para que pueda comenzar a interactuar
con los campos. Para cada uno, voy a decir que los objetos
auditables
sí crean una fecha, agradable y simple es igual a fecha hora punto porque estoy a
punto de guardar los cambios, hay que saber que
modificación
lo siento se hizo Fecha de modificación, es
la misma hora. Pero entonces piensa en esto. Busco
agregado y modificado, pero cada vez
que se agrega algo. Por supuesto, quiero
tener la fecha de creación, pero no quiero tener la fecha de creación cada vez que se modifique
algo. Ya ves lo sensible que es eso. Entonces estoy viendo tanto
agregado como modificado, pero estoy poniendo en
la fecha de modificación cada vez que algo
va a ser modificado. O, perdón, estoy poniendo
la fecha de creación cada vez que se
modifica algo, lo cual está mal. Todo bien. Voy
a sacar esa. Entonces cada vez que
golpeamos guardar cambios, quiero decir eso, se
modificó porque es verdad. Ya sea que se estuviera creando
o se estuviera modificando, fecha de modificación es no. Sin embargo, solo quiero
establecer la fecha de creación si El estado del punto de entrada es equivalente al estado de entidad punto creado o agregado, más bien, ¿verdad? Entonces cuando esté pasando, dirá, para esta entrada, voy a fijar la fecha de modificación. Entonces, ya sea que se esté creando
o modificando realmente, estamos estableciendo la fecha de modificación. Sin embargo, si se está agregando, entonces establezca la fecha de creación. De lo contrario, simplemente se saltará
esto. No va a hacer nada. Simplemente iremos a la siguiente entrada y haremos todo eso
hasta que esté hecho. Ahora bien, cuando termine toda esta
auditoría, lo último que queremos
hacer es finalmente guardar los cambios. Esto es como un Hurra final. Cualesquiera que sean los datos que surgieron
, no
sabemos, no sabemos qué tipo de conjunto de
base de datos de entidad es. Solo sabemos que todos estos tienen objeto de dominio
base en común. Y una vez que eso esté en su lugar, podemos bajar a
los campos de auditoría, independientemente del tipo de nivel
superior, voy a decir, para luego hacer los ajustes y
luego guardar los cambios. Ahora, antes de seguir adelante, acabo de notar que
hay cero referencias
a este método. En mi programa do CS, he desempolvado algunos de los viejos métodos que
hubiéramos usado, y cada uno de estos métodos
sí llama guardar cambios, pero luego mira eso,
guardar cambios una sincronización Sin embargo, hemos anulado
solo guardar los cambios. Ese es mi mal deslizamiento
mío de mi parte, ¿verdad? Entonces, el método de anulación que realmente
estamos
buscando es guardar cambios. Entonces lo que voy a hacer es reescribir esta anulación porque creo que hay varias Solo quiero asegurarme de que
obtengamos el correcto. Entonces tenemos guardar
cambios, guardar cambios y guardar cambios una sincronización
que toma dos parámetros, y luego este que toma un parámetro con un valor predeterminado. Entonces creo que ese es
el que
queremos porque si
usamos el otro, entonces tenemos que
proporcionar un lingote,
y bueno, ese
token de cancelación está ahí por defecto, pero luego queremos el que tiene el default donde sabemos que no tenemos que
proporcionar ningún parámetro Voy a usar esa y simplemente organizar mi código
aquí, ¿verdad? Ahí vamos. Así que estamos tarea de anulación pública
en Guardar cambio es una sincronización, y ese es el parámetro. Puedes seguir adelante y
hacer ese ajuste, y luego además de eso
necesitamos hacer este
syn porque bueno,
es un syn, entonces necesitamos que
sea un método asincrónico Y entonces si está
llamando a un sincrónico, es un método asíncrono, lo que significa que queremos usar el
método asíncrono aquí abajo también Yo solo puedo cambiar esa
para salvar cambia un pecado y requiere un peso. Entonces solo puedo pasarle un
peso a eso, y eso debería ser todo. Entonces tengo consistencia. Voy a usar el
mismo
token de cancelación en el parámetro
ahí mismo. Todo bien. Entonces con ese ajuste, no, estoy viendo que
se hacen las 12 referencias a los cambios de guardado. Entonces eso es un poco
mejor ahora. Todo bien. Entonces eso significa que cuando desde nuestro program.cs cuando
llamamos al contexto, realmente
va a
golpear nuestro nuevo Custom one, y luego va a
hacer todo esto antes de que llame a la base. ¿Todo bien? Entonces ese es el poder de
anular todo esto. Así que sigamos adelante y echemos
esto a dar una vuelta. Todo bien. Y lo que no
señalé qué métodos
desempolvé, disculpe Entonces estamos usando los métodos simples de operación de
inserción donde estamos agregando nueva liga
y equipos con liga, y estoy haciendo el registro de liga de
actualización simple, estamos actualizando el
récord de liga y el récord del equipo. Así que echando un vistazo en la consola y las
sentencias SQL que se están generando. Verás aquí que
tengo P tres, y estoy obteniendo ese
valor de fecha y hora ahí mismo, ¿verdad? Y cuando se está
insertando, van a entrar crear fecha, fecha de
modificación,
P dos y P tres. En consecuencia, aquí está P uno. Hay P uno, que
es nuestra fecha de creación. Y entonces tenemos P dos siendo nulo porque eso
sería creado por o modificado por Así vemos
que nuestras fechas van entrando en nuestra sentencia SQL
correctamente, ¿verdad? Entonces, una vez más,
esa sentencia SQL se genera en el momento en
que provoca cambios de guardado. Ahora, lo hemos sobrescrito para hacer algunas cosas adicionales
antes de esa declaración Q Entonces esa es una pequeña manera agradable inyectar tu propia pequeña lógica
y un poco de consistencia o
limpieza o cualquier cosa por el estilo
que necesites hacer antes de que los datos realmente se
comprometan a la base de datos, entonces siempre puedes anular los
métodos de contexto así Ahora bien, hay una
manera de extender aún más
el contexto DB
para facilitar ciertas cosas. Entonces en contexto, queremos
poner en tal vez modificado por, como un nombre de usuario o algo
que decir, quien lo modificó. Obviamente, no podemos hacer eso aquí porque no hay
forma de que me pase una cadena que represente
el nombre de usuario como o como cualquier forma de valor aquí porque los cambios seguros
solo están buscando esto. Entonces lo que podemos hacer es
extender nuestro contexto para aceptar datos adicionales que el contexto predeterminado no lo haría, y luego podemos masajear los datos antes de
llamar al contexto base. que podamos verlo más adelante, y creo que será
una actividad divertida. Bien.
35. Extender la DbContext: Oigan, chicos, bienvenidos de nuevo. Ahora la última vez que estuvimos aquí, estábamos extendiendo el contexto RDB para manejar un poco de trabajo de auditoría En otras palabras,
ampliamos los cambios de guardado o los anulamos
realmente para poder masajear nuestros datos un poco antes guardarlos en la base Ahora, vimos los beneficios de
esto porque ahora vemos que estamos obteniendo las fechas de
auditoría para la fecha de modificación y creación. No obstante, una limitación
es que no conocemos la persona que ha creado o modificado el registro en ningún
momento. Entonces esa es una de
las limitaciones solo
estamos sobrepasando
porque todavía estamos poco confinados a lo que nos depara los cambios
seguros predeterminados No puedo anular este parámetro cuenta
pedir un nombre de usuario. Entonces para contexto o
programa punto dice que
representaría la aplicación que está usando
el usuario, ¿verdad? Cuando alguien está usando la
aplicación web o escritorio, agregan un nuevo lead me
gustaría registrar quién hizo eso. Quiero su
nombre de usuario del sistema. No quiero ponerles su
responsabilidad, el usuario para
decirme quiénes son. Quiero saber quién
estaba conectado cuando se tomó
esta acción
contra este registro. Entonces sería bueno si
pudiera pasar por encima de
un nombre de usuario a los cambios de
guardado para que
pudiéramos usarlo en la
auditoría antes de guardar. Entonces con toda esa limitación que
entendemos la limitación y
lo que queremos lograr, voy a meterme enseguida en ella. Lo que vamos a hacer
es extender el contexto DB para tener otra cita de versión y
cita de la misma que va a hacerse cargo
del rol de guardar cambios o hacerse cargo de la anulación de los cambios de guardado y
luego entregarlo Entonces eso suena un poco más
complicado de lo que realmente es, y en realidad ya comenzó
el trabajo. Así que he creado una clase
completamente nueva, que creé justo en el mismo proyecto de datos que el contexto original de
la base de datos. Sólo lo estoy llamando auditable,
perdón, el contexto DB de la
liga de fútbol Ahora bien, este archivo de contexto DB de
la liga de fútbol de auditoría, es un resumen,
así que no conseguiría, ya
sabes, instanciado por sí Y hereda
del contexto DB. Lo que vamos a hacer es dejar contexto DB original
o
el contexto DB de la liga
de fútbol hereden
de nuestro contexto DB de
liga de fútbol Ahora bien, el beneficio de esto es
que con solo usar esta, obtenemos toda la funcionalidad
disponible en la versión
auditable,
pero luego la versión auditable nos
permite un poco más de
flexibilidad porque
no estamos confinados al contexto
real de DB y lo anulamos
en Entonces con todo eso
dicho y hecho, solo
voy a cortar este
método de guardar cambios AC de nuestro contexto DB de
liga de fútbol, y lo voy a colocar
en la versión abstracta, y voy a hacer algunas
modificaciones en este momento. Uno, voy a sacar este token de cancelación porque realmente no
necesito que lo
voy a
sacar por completo,
y voy a
permitir que llame
a los cambios de ahorro de base porque ese es el contexto DB, ¿verdad? Pero también voy a extender este método para tomar un
parámetro de cadena llamado nombre de usuario. Ahora bien, lo que esto está haciendo es
dejar que cada método de llamada sepa que deben pasar por encima un nombre de usuario para poder
llamar a este método correctamente. Y voy a
quitar este overide porque
ya no estamos anulando Sólo tenemos un método
llamado guardar cambios, que sólo va a llamar
a la base. Entonces es como una extensión o un método antes que
el método real. Ahora que tenemos este parámetro de
nombre de usuario entrando, ahora
puedo decir objeto
auditable punto en este punto
sería modificado por, y luego el modificado por
sería el nombre de usuario Y de igual manera, el creado
por sería ese nombre de usuario. Ahora, cero referencias.
¿Por qué es eso? Eso es porque en nuestro programa, sigue llamando a los cambios de guardado
predeterminados. Déjame encontrar uno de estos
métodos. Ahí está. Sigue llamando a
guardar cambios asíncrono, ese es el predeterminado
para el contexto No obstante, si miro las
sobrecargas disponibles para mí, veré que
hay una nueva sobrecarga, lo que me permite pasar
en esa cadena nombre de usuario Ahí vamos. Para que pueda
pasar un nombre de usuario. Digamos que el usuario de
gestión del equipo de prueba. Lo siento. Solo estoy tratando de ser
lo suficientemente explícito para que podamos ver en la consulta de la base de datos donde van esos cambios de
guardado. Esta es una actualización sencilla. Para que podamos buscar eso
o probar usuario actualizado. Déjame que sea sencillo.
Usuario de actualización de prueba. Este registro. No necesitamos eso. Voy a dejar
éste sin ningún nombre de usuario. Esto es modificar la liga. Este
no va a tener un nombre de usuario. Esta es la auditoría. Para que pueda cambiar el nombre de
mi liga. Para que
no tengas que hacer eso. Puedes usar tus datos
antiguos o poner tus propios datos, pero eso está bien. Pero solo voy a poner en algunas anulaciones test
audit create user, y luego voy a dejar éste sin ningún nombre de usuario, ¿verdad Entonces solo voy a ejecutar esto en este punto y veamos
exactamente qué pasa. Entonces cuando estoy viendo
algunas de las declaraciones, estoy viendo aquí en
el guardar los cambios que tengo esa auditoría de prueba
crear usuario. Ahí vamos. Entonces esa auditoría de prueba crear usuario fue quien creó
esa liga de pruebas de auditoría. Todo bien. Ahí vamos. Entonces esta persona, este usuario va entrando como P cero y P dos. Y si miramos P
cero es el creado por y P dos es el modificado por. Entonces así es como podemos meter a
esos usuarios en el sistema. Tomo nota, si bien puede que lo haya
citado duro aquí, una vez más, en una aplicación real
donde hay personas ingresan y así sucesivamente hay formas de obtener los nombres de usuario, y simplemente enchufarlo
en los cambios de guardado. En las aplicaciones web principales de .net, incluso
puedes inyectar el contexto CTP en
el camino y prescindir todo agarrarlo
y enviarlo, pero eso no Solo estoy tratando de
mostrarle cómo puede extender su contexto de base de datos
y manipular sus datos formas cada vez más creativas para
asegurarse de que tiene
esa integridad de datos cuando llegue a
la base de datos. Bien.
36. Implementar la auditoría completa de bases de datos: Muy bien chicos. Entonces la última vez que estuvimos aquí, sólo estábamos concretando cómo hacemos nuestra auditoría. Está bien. Entonces sobre saber auditar es sólo una fecha modificada y modificada al crear la asistencia creada por. Pero entonces puede que tengas otra necesidad donde tal vez necesites auditar todo el rollo. Por lo que podría estar en una base de datos separada o es una tablas separadas, o al menos eso siempre se hace tradicionalmente. ocasiones lo que la gente hace es poner disparadores en la tabla para que cada vez que algo se guarda, edita o borra,
automáticamente se escriben se requieren a otra tabla que está en camionaje. Qué actividad sucedió en una mesa en particular es tomar una copia de la mesa. Entonces vamos a tomar una copia de los valores originales previos a la operación, nuevos valores después de la operación, y serializarlos en una cadena y almacenarlos dentro de la base de datos. Cómo se puede leer. Eso depende de la aplicación y del desarrollador a la vez. Pero solo te estoy mostrando lo flexible que es EF Core en acceder a los datos antes y después del hecho y cómo podemos manipularlos durante. Entonces empecemos por crear una nueva clase y la voy a poner en el dominio. Probablemente podrías ponerlo en común, pero realmente va a ser una clase de dominio. Crea una nueva clase. No quiero llamarlo auditoría de TI. Por lo que auditoria va a tener algunos campos, va a tener el id estándar, una cadena para el nombre de la tabla. Entonces lo hacemos público. Y luego ponemos en los campos. Entonces va a tener el nombre de la tabla ID, datetime, lo que significa que la hora, por supuesto que se ingresó, el valor clave. Entonces, cualquiera que sea la clave primaria fuera del registro que se está auditando, los valores antiguos del registro y los nuevos valores del registro. Entonces, después de haber replicado esa clase de auditoría, entonces puedes pasar a nuestro contexto de base de datos auditable. Y vamos a añadir ese conjunto de DB, ¿verdad? Entonces va a estar en el contexto de DB auditable. ¿ Necesita auditoria de conjunto? Y yo sólo lo llamo auditorias. Entonces vamos a entrar en engañar cambios. Y en realidad quiero hacer algunas cosas antes de guardar los cambios, porque antes de guardar los cambios, necesitamos tomar una copia de los datos que están entrando, ¿verdad? Entonces justo arriba donde sacamos nuestros cambios de camión y sabemos lo que pasó y demás. Voy a ver en antes de guardar cambios, ¿verdad? Este método no existe, así que solo controlaré punto y generaré ese stub de método. Y ahí vamos. Entonces esto va a devolver una lista de otra clase que estoy a punto de crear llamada entrada de auditoría. Entonces si hago Control dot, Veamos qué puede hacer Visual Studio por nosotros. Dice que puede generar un tipo llamado entrada de auditoría en su propio archivo. Por lo que sólo vamos a seguir adelante y crearlo en su propio archivo. Sin daño, sin falta. Saltar a entrada de auditoría. Entonces una entrada de auditoría básicamente va a ser una obstrucción de lo que necesitamos exactamente, ¿verdad? Entonces vamos a arreglar un poco esta clase. Entonces voy a decir entrada de auditoría pública. Entonces ese es básicamente el constructor. Y quiero entrada de entidad. Entonces sabemos qué es la entrada de la entidad. Esto viene de EF Core. Y sólo lo llamaremos entrada de entidad y seguro. Y luego vamos a usar ese constructor para inicializar nuestra propiedad. Por lo que puedo controlar eso y decir Crear entender propiedad llamada entrada entidad. Y eso lo hace para mí automáticamente, ¿verdad? Entonces voy a tener otros campos ese tipo de mucho lo que teníamos en auditoría, ¿no? Entonces voy a tener nombre de tabla de cadenas. También voy a tener buenos, viejos valles y nuevos valores y bueno Key Vault se
trata de no se trata de lo que voy a cambiar los tipos de datos de esos. Entonces tenemos el nombre de la tabla, tenemos el valor clave que realmente va a ser como un diccionario. Alguien para cambiar el tipo de datos a diccionario de cadena y objeto. Entonces si nunca has trabajado con diccionarios es igual un par de valor clave para que pueda resolver JSON. Y eso es lo que es un diccionario. Una cadena sería la clave y los objetos serían
los datos que van al lado de la clave. Por lo que el punto de control incluye eso. Y voy a simplemente inicializarlo para que nunca se sepa. Entonces solo toma esto y c es igual a un nuevo diccionario de cadena, un objeto. Y más o menos eso es todo lo que vamos a hacer por los valores antiguos y los nuevos. Y hacemos las mismas inicializaciones y ves todo ese tipo de luce consistente y pequeña bala más aterradora pronto verás lo que buscamos lograr. La siguiente línea va a ser para propiedades temporales. Entonces voy a decir una lista pública de entrada patrimonial. Que es también de proveniente de entradas de entidad biblioteca de freeware tendencias seguimiento de cambios, ¿verdad? Por lo que se ve una lista de entrada de propiedad, las propiedades
temporales es igual a una nueva lista. Voy a tener un método rápido Eso es sólo devolver nuestra propiedad más bien eso es devolver un booleano a ver tiene propiedades temporales. Entonces en cuanto explique para qué significa realmente las propiedades de temperamento o se utilizarán. Pero entonces vamos a tener otro método que realmente se va a construir
o auditar requerido sobre lo voy a llamar a auditar. Está bien. Simplemente tendría que incluir cualquier espacio de nombres allí. Ahí vamos a auditar. Y entonces podemos empezar a construir todas las funcionalidades. Entonces cuando hablamos de auditar, estamos hablando de construir la entidad real, su historial. Por lo que var auditorias es igual a nueva auditoría. Inicializar un nuevo objeto de auditorías de tipo. Y luego comenzaremos a llenar todos los campos de la auditoría. Por lo que puedo usar este inicializador de objetos. Y entonces puedo decir, de acuerdo, ¿El tiempo sabemos que eres datetime dot nl no-brainer, ¿verdad? Entonces estos son los puntos de tiempo. No. ¿ Verdad? Entonces nombre de la tabla, eso es bastante fácil y no debería haber usando un punto y coma, disculpas. El nombre de la tabla es igual al nombre de la tabla proveniente del local. ¿ Está bien? Entonces tenemos los valores clave, que sería una serialización de los valores clave entrando, ¿verdad? Entonces solo estoy viendo valores clave es igual a JSON convertir, ver serializar o valores de objeto y clave, ¿verdad? Así que bastante recuerden que este es un diccionario. Entonces vamos a tener la llave, que va a ser como identificación. Vamos a tener que el valor se almacene como un objeto, por lo que es un ID de cadena, o en nuestro caso estamos usando int ids. Sea lo que sea, sólo va a tener ese par de valor clave y sólo vamos a estar almacenándolo como JSON. Y francamente, eso será lo mismo para los valores antiguos y los nuevos valores. Pero luego hay una especie de giro con esos. Entonces vamos a estar viendo algo así como todos los valores es igual a todos los valores conos de punto siendo 0. Si es 0, entonces podemos almacenar nulo. De lo contrario queremos convertir el volumen que viene del valor clave aparece. Conoce la relevancia de eso. Si estamos haciendo ciertas operaciones como insertar nuestro registro, entonces no hay valor viejo para ese disco porque es un registro totalmente nuevo. Por lo que no hay manera de conseguir los viejos valores. Por lo que va a estar registrando para ver si había algún valor viejo para ser almacenado en este registro si no entonces nulo porque entonces podemos suponer que se trataba de una operación de adición. Y entonces podemos seguir adelante y serializar los valores si en caso de que fuera yo no comí o una actualización. Entonces de la misma manera que hicimos lo mismo, haremos nuevos valores. Entonces voy a duplicar esta línea y cambia por lo que dos nuevos valores. Y dondequiera que hubiera una escisión, nuevos amiguitos. Entonces si no hay nuevos valores, almacene nulo, aunque ojos almacenados en los nuevos valores. Creo que voy a añadir un campo más y ese es el axón. Entonces voy a, en la tabla de auditoría sumar acciones para que sepamos qué tipo de operación se estaba realizando, qué es lo correcto. Entonces acción, y yo haré lo mismo aquí, te llamó acción. Y luego para auditar, diré que la acción es igual a nuestra acción local. Yo escuché. Entonces sabemos lo que estaba pasando ahora después de haber construido todo este objeto de auditoría, se supone que
este método está devolviendo ese objeto de auditoría. Por lo que acabamos de devolver auditoría. Eso es todo para nuestra auditoría. Entra al menos por nulo a medida que
avanzamos, podríamos ver todos los ajustes que se necesitan. No, volveremos a saltar a nuestro contexto de base de datos auditable. Y para mí esto más fácil, sólo
voy a sacar todo esto. Voy a cortarlo y lo voy a poner dentro de nuestro nuevo método. Entonces, antes de guardar cambios, estas son cosas que queríamos hacer de todos modos, ¿verdad? De acuerdo, así que voy a refactorizar un poco esto en lugar de
tratar de conseguir sólo estas entradas el miércoles, lugar de pasar por un proceso de eliminación. Entonces fui a ver si obtienen las entradas del instructor donde el estado no es igual a desprendido y no es igual a en tramposos camino estaría capturando más escenarios en el medio, ¿verdad? Entonces consígueme las entradas que no fueron desligadas o sin cambios y entonces esos son los intereses por los que estamos iterando. Ya ves aquí eso es que se está quejando de nombre de usuario. Veamos qué controller.js para nosotros, podemos generar una propiedad que está bien. De acuerdo, esto solo agrega el parámetro. usuario perimetral generado. Había todo tipo que buscaba. Entonces ahora tenemos el nombre de usuario i, podemos Boston ese nombre de usuario encendido antes, ver si cambia y todos están contentos. Muy bien, Así que en ninguna parte consiguiendo todos los intereses no se tocan, no sin cambios en nuestro establecimiento esas columnas de auditorías para ellos. Ahora antes de meternos en eso para cada uno, quiero una nueva lista de entradas de auditorías y estaremos compilando esta lista a medida que pasemos. Entonces por cada entrada, después de que pase por estas pruebas iniciales, voy a tratar de ver quiero una nueva instancia de póliza de ingreso de auditoría en esa entrada viniendo de nuestro EL camionero. Correcto. Entonces recuerda que fue cuando tuvimos el constructor y auditoría para asegurar que la entrada Tolkien como su parámetro. Entonces voy a obtener el nombre de la tabla a través de ver entrada de
auditoría nombre de la tabla de punto es igual a y luego te das prisa y sientas que es igual a entry.metadata. Entonces solo estoy mostrando una gran cantidad de datos. En realidad se puede conseguir un barco, algo que es un perno para ser guardado en la base de datos. Puedo obtener los metadatos, no la relación. Déjame ver tu evento relacional necesita
incluir referencia faltante o simplemente deletrearlo correctamente. Entonces punto relacional o en realidad creo que es un puntonet Core de tres puntos uno. Si core 3.1, aquí está, obtener el nombre de la tabla. Ahí vamos. Por lo que en la corte dotnet Core 5, es aún más fácil obtener un nombre de tabla. Apenas veo GET nombre de la tabla. Está bien. Y luego vamos a añadir esta nueva entrada de auditoría a nuestra lista. Entonces sólo voy a decir Agregar y auditar entrada como hecho conjunto. Hay otro campo que me gustaría sentar a partir de este punto, y esa sería la acción. De acuerdo, entonces necesitamos saber qué acción se está llevando a cabo. Y entonces sólo pude ver el punto de entrada, estado, punto a cadena, esa es la subasta. Sepan que tenemos esa parte del camino y nos enfoquemos en las propiedades. Por lo que necesitamos evaluar ciertas propiedades, una, para copiar sus valores, ya sean viejos valles o nuevos padres o la clave primaria igual y remota. Ese es nuestro registro de auditoría, sí tiene un campo específico para la clave primaria. Entonces lo que podemos hacer fácilmente es empezar con un foreach y podemos decir var propiedad en entrada, Propiedades de pensamiento. Entonces esto es usando lo que llamaremos reflexiones y todo lo que es uno de esos gran mesada nos lo dan versiones más recientes de C sharp. Por lo que podemos ver si la propiedad, lo siento, si la propiedad es temporal. Por lo que esto nos permitiría evaluar si hay una bodega de valor más bonita dentro de la propiedad. Entonces cuando más reciente, experimentando con la adición de registros y así sucesivamente, verías que el valor id tiene un menos, creo que eso es int Min menos 2 mil millones y algo valor en él. Ese es en realidad un valor temporal hasta que se guarda el valor. Correcto. Entonces queremos ver si la propiedad es temporal que los puntos de auditoría. Las entradas de auditoría son propiedades temporales en este inmueble. Está bien. Entonces esto es todo lo que podemos saber si esto se va a agregar o no. Verás más adelante por qué esto es tan importante. Entonces después de eso podemos continuar. No necesitamos hacerlo ninguna otra operación en esta propiedad. Si se trata de una propiedad temporal, sólo lo
agregamos al registro y luego simplemente continuamos. No hay necesidad de preocuparse por ello. No hay otras cosas que podamos necesitar hacer si no está cayendo en esa categoría es obtener el nombre de la propiedad. Que una vez más, tendré que apoderarme de propiedad.metadata y
sólo usamos mi portapapeles propiedad dot data dot name. Entonces estoy recibiendo inflamación y eso es lo que son los metadatos. Si el property.me es clave primaria. Y ese es un método. Entonces estamos viendo si estamos tratando con una clave primaria, entonces queremos almacenar los compañeros clave. Entonces va a parecer similar a lo que hicimos aquí. Siempre estamos viendo que la auditoría IS introduce valores clave y luego obtenemos el nombre de la propiedad como la clave o el subíndice del IRI. Y estamos almacenando el valor. Entonces vamos a seguir adelante y almacenar eso. Entonces esto es todo lo que obtenemos que aparezca el valor clave, ¿verdad? Entonces eso es cadena en el diccionario, eso es como nombre de propiedad. Y entonces el valor o el objeto sería el valor actual de la clave primaria. Después pasamos a un interruptor donde vemos Consígueme el estado de entradas. Por lo que cambia el estado de entrada. Y luego vamos a hacer algunos casos. Vamos a comprobar si se está agregando, entonces necesitamos almacenar los nuevos valores con el nombre de la propiedad en el valor actual. ¿ Está bien? bien fue si se está borrando, necesitamos almacenar los valores antiguos con el nombre de la propiedad y el origen de nosotros el valor actual ECF y el origen del valor. El valor actual es lo que se está poniendo saber y los valores originales, lo que fuera antes. Entonces eso viene muy bien saber cuando estamos comprobando si el estado NTT está en un estado modificado en ese punto donde estamos viendo si sí lo modifica en una propiedad se ha modificado, correcto. Entonces estamos viendo si cambias esta propiedad en particular que estamos viendo, entonces queremos saber cuál era la propiedad original de Ardi y cuál es el nuevo valor de propiedad. Está bien. Entonces para eso es esa declaración de cambio. Y bien, No, eso es todo lo que estoy haciendo en esto. Entonces, una vez más, queremos almacenar si
es apropiado si es una propiedad temporal, si lo es, eso significa que es un registro que es un perno a agregar y
no hay clave primaria porque esto está encendido antes de guardar los cambios. Entonces nada realmente está pasando por el momento. Formas claves primarias. No obstante, si hace hasta clave primaria la cual sólo estaría presente si fuera en borrar o una modificación, entonces vamos adelante y hacemos una nota de cuál es el valor clave. De lo contrario para el resto de los valores donde se registra cuáles son los nuevos valores, cuáles son los valores antiguos, justos borrados, y ambos si se está modificando. Entonces, pasando, no, necesitamos realmente guardar estas entradas de auditoría o al menos construir una lista de auditorías para ser tamizadas más adelante, correcto. Entonces voy a hacer un para cada ojo otra vez, no
quiero guardar para cada entrada de auditoría en y voy a conseguir que esa lista de entradas de auditoría atracen. Y quiero fuera de ellos donde tengamos nuestra expresión Lambda, q-dot tiene propiedades temporales. Podemos ver es igual a caer como significado que no tiene ninguno o puedo usar. No digo que haya estado haciendo esto con fines de legibilidad. Entonces estamos ahí hay propiedades temporales nulas y no puedo usar la entrada de auditoría aquí otra vez, déjame solo ver auditoría pendiente para asegurarme de que me dejes usar esa entrada de auditoría pendiente. Está bien. Entonces por cada entrada de auditoría pendiente en la lista que hemos compilado hasta este punto donde hay propiedades temporales nulas, entonces queremos agregarla a las auditorías DB sentarse por plomo a lesión. Por lo que pendiente de entrada de auditoría punto y luego aquí es por qué teníamos eso para auditar método. Entonces recuerda que los dos ruido de auditoría cuando tomar cualquier valor era Boston y lo que fuera sentado aquí y en realidad crear en auditorias registro de retorno. ¿ Verdad? Entonces solo estamos viendo todo lo que acabamos de compilar, todos los pares de valor clave en. Entonces, lo convierte en un registro de auditoría real y herramienta de edición o DB sit. Después de todo eso, quiero devolver las entradas de auditoría que no tienen o lamentan que duales tengan propiedades pendientes, propiedades temporales. Por lo que quiero regresar donde tienen propiedades pendientes. Y claro que somos nosotros para ser una lista porque necesito células que devuelvan una lista. Ahí vamos. Entonces eso es lo que está pasando antes de guardar cambios. Todavía lo estoy consiguiendo, Aaron. Creo que es porque lo hice está dentro de esto para cada uno y esa es su tarjeta. Entonces esto debería pasar fuera de eso por cada uno me disculpo. Entonces déjame llamarlo rápido. Y al final del método, pasamos por auditorías compiladas y regresamos las que son temporales. Ahí vamos. Todo el mundo está contento con eso. No, ya lo hemos hecho antes. Guardar cambios. Está bien. Y luego seguimos adelante y guardamos los cambios. Ahora lo que va a pasar después de guardar los cambios a menudo en este punto es que vamos a tener todos los intereses de auditoría que ha tenido los valores que quiere que se agreguen donde aún no tenían identificación. Todos siguen almacenados dentro de este nulo. Yo quiero volver atrás y actualizar el ID válido saber que se han almacenado. Entonces en lugar de regresar en estos puntos, voy a poner esto en una variable. Yo sólo voy a llamarlo. Resultado o resultado. Entonces solo estamos almacenando lo que sería esto, ¿verdad? Y luego vamos a tener otro método al que voy a llamar después de guardar cambios sobre dónde póliza en las entradas de auditoría. Correcto. Por lo que obtenemos las entradas de auditoría que estaban en estado de identificación temporal. Vemos que g y g es y todo lo que han sido actualizados. Ahora tenemos que hacer algo después de los cambios de guardar. Entonces voy a colapsar el de antes y sólo voy a generar este método. Y con eso hecho, lo que vamos a hacer es pasar por las entradas de auditoría y comprobar si lo que sea necesario que suceda, ¿verdad? De hecho, esto puede que ni siquiera tenga que suceder. Entonces voy a decir si las entradas de auditoría no son iguales a nulas, por cualquier razón podría ser nulo. O auditar lesiones conos de puntos es en realidad mayor que 0, lo que significa que en realidad tenemos cosas que procesar después. Entonces puedes llamar a este método. ¿ Está bien? Entonces dentro del método, lo que tenemos que hacer es pasar porque en este punto estamos asumiendo que algo está dentro de las entradas de auditoría, sólo se
llegaría aquí. Si algo fue, entonces lo que vamos a hacer es evaluar cada entrada de auditoría y poner en marcha esta lista. Y luego estamos consiguiendo las propiedades en cada uno de estos, por lo que dos por cada listado para cada uno. Entonces voy a decir conseguirme cada prop en auditoria entrada dot propiedades temporales. Entonces recuerda que compilamos una lista de todas las propiedades temporales. Después fui a tener una declaración if para ver si la propiedad es nuestra clave principal, entonces agregamos el valor clave para ser el valor actual. Está bien. Por lo que sólo estamos haciendo una rápida actualización de ese valor de entradas de auditoría para ser el valor actual. De lo contrario, el nuevo valor es nuestro valor actual. Entonces solo estamos viendo si es una clave primaria, lo cual es más que probable por qué terminaría siendo temporal. Si se estaba agregando algo, actualizado al volumen actual, sepa que todo se ha guardado. De lo contrario, si no fuera nuestra clave principal, que como me siento ahí puedo pensar en un escenario donde tendrías un valor de madera para XOM. Esa no es la clave primaria. Pero en ese caso, aún lo
actualizamos. No hay problema. Está bien, entonces después de eso, hacemos el para cada uno en, para cada uno que estamos ahorrando, que definitivamente lo vamos a agregar a la auditoría. Apenas llamo agregamos la auditoría interesada en los cambios antes de guardar. Por lo que solo auditorias punto sumar bajo las dos auditorias para que pueda ser convertida. Después regresamos un guardar cambios. Entonces tenemos que llamar a un mar de cambios en ese punto. Está bien. Ahora después de haber guardado esos cambios, podemos devolver resultado aquí o guardar resultados más bien. Entonces eso es realmente lo que he implementado para auditar en múltiples aplicaciones. Y funciona bastante bien porque como dije, realidad
es solo almacenar representaciones de cadenas de cómo sería todo el registro. Y tenemos los valores antiguos y los nuevos valores para una comparación lado a lado. Por lo que en una interfaz de usuario podría imprimir fácilmente resultado porque es JSON, puede
que no sea fácilmente legible por humanos. Por lo que quizá quieras ajustarlo un poco para que los detalles presentaran una B, es más legible, pero al menos puedes ver todo lo que está pasando. Mantenga un registro de todo lo que se está borrando, modificando, o agregando aplicación de garganta, sean cuales sean valles donde en ese momento. Para que pueda seguir adelante y hacer algunas pruebas, hacer algunos protistas, y mirar en esa auditoría estable, por supuesto, ya sabes, con todos esos cambios, tenemos que arrancar auto nueva tabla. Entonces si la migración de anuncios y decimos agregamos tabla de auditoría. Y luego después de conseguir esa migración tenemos que ver los datos es. Y con todo eso hecho, puedes seguir adelante y probarlo y hacerme saber cómo funciona para ti.
37. ACTUALIZACIÓN: Implementa la auditoría completa de bases de datos: corrección de datos: Hey chicos, Esta es una solución rápida para nuestro video anterior. Habrías configurado tu auditoría y la auditoría de base de datos completa. Y veremos cómo serializa todo a JSON, lo
almacena en la base de datos. No obstante, si intentas hacer múltiples operaciones, pero para frenar, podrías tropezar con una situación difícil en la que se queja de una tipificación
para un campo de auditoría o un registro de auditoría cuando eso realmente no debería estar sucediendo. Y yo sólo estoy aquí para mostrarles lo arreglado para eso. Entonces en nuestra mano antes de guardar cambios o guardar cambios, lo que debería pasar es que esto debería filtrar cualquier cosa que esté sin cambios ya tocado para saber sabemos que el estado de la entidad, apuesto Así que cualquier cosa sea inserto va a conseguir el agregó. Y entonces sabemos que tenemos el estado de entidad para borrado y modificado o así. Pero entonces la razón por la que estamos excluyendo a estos dos es que no necesitamos auditar nada que esté desprendido, lo que
significa que no está siendo camionada, nuestra no debe ser rastreada o sin cambios, lo que significa bueno que no pasó nada. Así que lee esencialmente lo que sucede es que una vez que se llama realmente a Save Changes, lo que sea que se rastrea automáticamente pasa a un estado onchange. Entonces si haces múltiples operaciones, entonces vas a terminar con entradas de auditoría que se están guardando. Y luego vas y tratas de decir algo más en el marco sigue rastreando los objetos antiguos que se guardaron más recientemente, incluyendo el registro de auditoría. Entonces por eso habría que
filtrar en este punto porque está conociendo un estado onchange. No obstante, por la razón que sea este filtro en realidad no está funcionando como me hubiera gustado al tal vez trabajando para ti, Amy anatta de este programa, eso es bueno. Pero he visto que este problema ocurrió más de una vez. Entonces sólo voy a mostrarles este arreglo para ello. Y es menos una solución sofisticada. Todo lo que voy a hacer es invertir la condición y eso funciona mejor para algunos. Entonces lo que vamos a hacer es decir, dame las entradas donde sabemos que queremos probarlas, lo que significa que el estado es equivalente a muerto, o es herramienta equivalente modificada. Y luego uno más. O es equivalente a los BreakLine borrados. ¿ Verdad? Porque sabemos que queremos rastrearlos. No queremos rastrear a los otros dos. Pero así cuando estamos tratando de excluirlos por la razón que sea, la exclusión podría no funcionar como debería. Entonces eso está bien. Simplemente vamos a trabajar nuestros propios que aún manteniendo la calidad y la integridad de nuestro código. No estamos en ninguna parte viendo darnos los que sabemos definitivamente vamos a querer auditar. Entonces estamos consiguiendo esas entradas y entonces todo lo demás
caería en línea porque hay que tener o
declaración de caso en base a qué estado es el que se necesita agregar al ingreso de auditoría. Entonces esa es una solución rápida. Si tuviste esa dificultad, podemos hacerlo y estoy seguro de que obtienes una mejor experiencia. Y si no, claro, seguiremos investigando y mirando porque todos estamos aprendiendo rojo. Esta es una biblioteca muy compleja y sólo estamos haciendo todo lo posible para sacar el mejor provecho de ella.
38. Validación de datos con las anotaciones de datos: Oigan, chicos, bienvenidos de
nuevo. En esta lección, veremos poner
restricciones y limitaciones, reglas
generales alrededor de
las propiedades y los valores que se
les permite tener. Ahora bien, habría usado la
palabra restricción más de uno. Y eso hubiera sido más específico de las migraciones
donde vimos que se estaban agregando restricciones para
las relaciones de clave
externa o por la singularidad y
cosas así Pero entonces esas son
todas migraciones basadas en algunas de las reglas
que estamos configurando en nuestro modelo creando
y basadas los tipos de datos y lo que establecemos como
referencia de clave externa y tal Ahora, además de esas situaciones
específicas, hay momentos en los
que quieres ser un poco más calculado y tener un conocimiento más práctico de lo que se está almacenando y
cómo se almacena. Entonces un ejemplo práctico. Cuando miramos al equipo, vemos que tenemos
una cadena para nombre, que se traduce a
un RCR en la base de datos, pero luego es VRTR Max Realmente queremos VrTRmx
para un nombre de equipo, ¿verdad? Entonces ahí mismo, estamos abriendo la base de datos a la
posibilidad de que alguien pueda poner un ensayo completo en ese campo y llamarlo
nombre de equipo. No necesariamente queremos eso. Otras restricciones pueden
incluir valores predeterminados. Entonces habíamos agregado estos objetos
de dominio base. Y solo estoy usando
esto un ejemplo donde tenemos la fecha y hora Pero entonces también puede
haber situaciones en las que desee valores predeterminados
en estas propiedades. Entonces, si no se proporciona un valor desde la interfaz
o desde el usuario, aún
quieres que tenga un valor. Echemos un
vistazo a limitar algo de lo que nuestras columnas de cadena
pueden tomar, por ejemplo. Entonces desde el contexto DV, y esto está usando API fluida. Entonces, antes habríamos mirado la API
fluida cuando
estábamos especificando ciertas reglas torno a lo que cada
entidad puede tener. Todas estas líneas
de códigos o bloques de código realmente son fluidas
basadas en API fluidas. Entonces, lo que estamos haciendo ahora es usar API
fluida para alguna validación. Entonces quiero decir constructor de
modelos punto, y luego va a
estar en equipo esta vez. Entonces voy a
decir propiedad punto, que luego se abre para
otra expresión Lambda. Voy a usar P como mis fichas. Voy a decir P punto, y después puedo elegir la
propiedad que me interesa. Entonces sí dije nombre. Y luego después de eso, puedo
decir qué limitaciones tiene. Entonces puedo decir a la base de datos
que se requiere, o tiene un tipo de
columna específico. ¿Y si no necesariamente
quisiera que fuera VT? Y si quisiera que fuera VT. Por ejemplo. Y si
quiero establecer una longitud máxima, que es lo que estamos a punto de hacer. Entonces voy a decir longitud máxima, y entonces todo lo que necesita
es un valor entero. Voy a decir que ningún equipo
debería tener un nombre que tenga
más de 25 caracteres de largo.
Creo que eso es razonable. Hay algunos equipos con nombres
largos como Barca, Munch y Gladbach
allá en Pero creo que 25 es
suficiente o vamos a darle golpe hasta 50 para estar en
el lado extremadamente seguro. Por lo que ningún equipo debería tener jamás
un nombre que supere los 50. Ahora, haciendo la
luz de las reglas, esto realmente
establece la restricción
para una propiedad, y es prácticamente
una propiedad a la vez. Pero puedo hacer esto por
múltiples entidades. Entonces quiero esa misma
restricción en una liga. No quiero que ningún nombre de
liga sea un ensayo, y no quiero que ningún nombre
de entrenador sea demasiado
largo. ¿Todo bien? Otras cosas que podría hacer, podría configurar esta
propiedad como índice. Cuando hablamos de índices, son realmente puntos de búsqueda
de alta velocidad. Voy a quitar, acabo de duplicar esa línea, y en vez de
decir propiedad de punto, voy a decir punto tiene índice. Y entonces esto
ahora me va a
pedir una expresión Lambda. Así que voy a
usar simplemente H como estamos haciendo index y voy a decir que
el índice está en el nombre. Eso quiere decir que si
buscamos por el nombre, debería ser una velocidad alta. Punto para los datos, por lo que la consulta debe ejecutarse con
relativa rapidez. En realidad puedo simplemente
hacer lo mismo por nuestra liga y
por nuestro entrenador. Observe que lo que estoy haciendo
es simplemente copiar y pegar y reemplazar
los nombres en consecuencia, porque todos tienen estructuras
similares Todo lo que probablemente
quieras
hacer sería especificar que estas columnas deben ser únicas o cualquier valor que vaya en
ellas debe ser único. Entonces un estudio de caso para eso, bueno, no
querrías dos
equipos con el mismo nombre, aunque es muy probable. No querrías dos
ligas con el mismo nombre, aunque eso es,
supongo, menos probable. Pero en un
entorno más práctico si estás haciendo una base de datos para un sistema
de gestión escolar o un libro, Almacenamiento. Tienes el ISBN, que es un
número único para cada libro, o tienes el número de identificación de un
estudiante, que es diferente del ID incremental
predeterminado