sql >> Base de Datos >  >> RDS >> Sqlserver

Actualice el valor de la clave principal utilizando el marco de la entidad

tengo un doctorado en cs, en el área de bases de datos, por lo que esta respuesta será un poco diferente a la perspectiva de los programadores. Con todo el respeto a Oliver Hanappi, una clave puede cambiar y ocasionalmente cambia si no es una clave sustituta. P.ej. Una clave natural o una clave compuesta. Por ejemplo. Es posible cambiar su SSN en los EE. UU. Pero muchos programadores a lo largo de los años considerarían esta clave inmutable y la usarían como tal. Es mucho más común cambiar una clave primaria compuesta formada por claves externas.

Estoy tratando con una base de datos que tiene una relación ternaria. Específicamente tres entidades (con claves externas siendo claves primarias sustitutas en sus respectivas tablas). Sin embargo, para preservar la relación entre dos entidades mientras se cambia la tercera entidad requiere cambiar parte de la clave principal de la tabla de intersección (también llamada tabla de combinación pura en MSDN). Este es un diseño válido y solo podría mejorarse eliminando la tabla de intersección de relaciones ternarias y reemplazándola con dos tablas de relaciones binarias (que pueden tener sus propias claves sustitutas). EF manejaría esto bien. Este cambio de diseño haría un modelo (Muchos->muchos)->muchos o Padre1-Padre2 -> Hijo-nieto (si no está claro, lea el ejemplo a continuación). El marco de la entidad funcionaría bien con esto, ya que cada relación es realmente una relación de uno a muchos. Pero es un diseño loco desde la perspectiva de DB. Déjame mostrarte un ejemplo de por qué.

Considere que el Curso, el Aula y el Instructor están asociados entre sí en una clase. La clase podría incluir:CourseID, ClassroomID, InstructorID como claves externas y contener una clave principal compuesta que incluya las tres. Aunque es un modelo ternario claro y conciso (relación de 3 vías), podríamos dividirlo en relaciones binarias. Esto daría dos tablas de intersección. Agregar claves sustitutas satisfaría a EF de la siguiente manera:

Clase(SurrogateKeyClass , ID del instructor , ID del curso )

ClassRoomUsed(SurrogateKeyClassroomUsed , Clase de clave sustituta , Id. de salón de clase )

El problema con este diseño es que podríamos tener el mismo curso e instructor asociado varias veces, lo que evita el modelo anterior. Para evitar este problema, puede agregar una restricción en la base de datos para la unicidad de los dos campos de ID, pero ¿por qué querría hacer esto cuando solo está tratando con claves sustitutas para empezar? Sin embargo, esta solución funcionaría lo mejor que puedo decir. Sin embargo, este no es un diseño de base de datos lógico debido a la restricción única antinatural requerida en la base de datos.

PERO, si no quiere cambiar su base de datos o no puede cambiar su base de datos, aquí hay una segunda solución :Las tablas de intersección/asociación son solo eso, enlaces que unen dos o más entidades. Si uno cambia, elimine la asociación y vuelva a crear una nueva que tenga las claves externas apropiadas (propiedades de navegación). Eso significa que no se le permitirá requerir entidades secundarias en ninguna de las relaciones, pero eso es extremadamente común.

¡Sugeriría que Entity Framework (en el futuro) nos permita a aquellos de nosotros que podemos diseñar un modelo DB elegante cambiar partes de claves en las tablas de intersección/asociación cuando queramos!

Otro ejemplo gratis:

Considere una Asociación de Estudiante, Curso, Grado. Los estudiantes están asociados con un curso a través de una calificación. Por lo general, se trata de una asociación de muchos a muchos entre el estudiante y un curso con un campo adicional en la tabla de asociación llamado calificación (las tablas de asociación tienen datos de carga útil como calificación, las tablas de intersección no tienen una carga útil y en MSDN se denominan tablas de combinación pura en arrendamiento en un solo lugar):

Estudiante(IDEstudiante , ....)

Curso(IDCurso , ...)

Tomando(IDEstudiante , ID del curso , grado)

Si alguien comete un error de ingreso de datos desde un menú desplegable y coloca a un estudiante en la clase equivocada, le gustará que lo cambie más tarde seleccionando el menú desplegable nuevamente y seleccionando un curso diferente. En segundo plano, deberá eliminar el objeto EF de la tabla Toma y volver a crearlo sin perder una calificación, si la hay. Simplemente cambiando la clave foránea CourseID parece una mejor alternativa. Piensa en tu propia asociación si esta parece artificial, pero como profesor fue natural para mí.

Conclusión:cuando tiene una serie de relaciones, puede ser mejor no permitir la conexión en cascada y/o el cambio de FK, pero existen escenarios lógicos/razonables en los que es necesario, incluso si no se recomienda como una mejor práctica en general .

Este problema puede manifestarse con las siguientes Excepciones dependiendo de si está cambiando la propiedad de navegación o la propiedad clave en el modelo respectivamente:

Ocurrió una violación de restricción de integridad referencial:una propiedad de clave principal que forma parte de la restricción de integridad referencial no se puede cambiar cuando el objeto dependiente no ha cambiado, a menos que se establezca en el objeto principal de la asociación. El objeto principal debe ser rastreado y no marcado para su eliminación.

La propiedad 'X' es parte de la información clave del objeto y no se puede modificar.