Tengo un Ph.D. en cs: en el área de Bases de datos, esta respuesta será un poco diferente de la perspectiva de los programadores. Con todo respeto a Oliver Hanappi, una clave puede cambiar ocasionalmente si no es una clave sustituta. P.ej. Una clave natural o una clave compuesta. Por ejemplo. Es posible obtener su SSN cambiado en los Estados Unidos. Pero muchos programadores a lo largo de los años considerarían esta clave como inmutable y la usarían como tal. Es mucho más común cambiar una clave primaria compuesta compuesta por claves externas.
Estoy tratando con una base de datos que tiene una relación ternaria. Específicamente tres entidades (con claves externas que son claves primarias sustitutas en sus tablas respectivas). Sin embargo, para preservar la relación entre dos entidades al cambiar la tercera entidad, requiere cambiando parte de la tabla primaria de la tabla de intersección (también llamada tabla de unión pura en MSDN).Este es un diseño válido y solo podría mejorarse eliminando la tabla de intersecciones 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 Padres1-Padres2-> 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 una perspectiva 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 foráneas y contener una clave primaria 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. Adición de claves sustitutas satisfarían EF como sigue:
Class (SurrogateKeyClass, InstructorID, courseid)
ClassRoomUsed (SurrogateKeyClassroomUsed, SurrogateKeyClass, ClassRoomID)
El problema con este diseño es que podríamos tener el mismo curso y el instructor asociado mult veces, lo que el modelo anterior evita. Para evitar este problema, puede agregar una restricción en la base de datos para la unicidad de los dos campos 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ógica debido a la restricción única no natural requerida en el DB.
PERO, si no desea 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 elegante modelo de DB cambiar partes de claves en tablas de intersección/asociación cuando queramos!
Otro ejemplo de forma gratuita:
Considere un estudiante, curso, Asociación grado. Los estudiantes están asociados con un curso por un grado. Por lo general, esta es una asociación muchos a muchos entre Estudiante y un Curso con un campo adicional en la tabla de asociación llamado grado (las tablas de asociación tienen datos de carga útil como grado, las tablas de intersección no tienen una carga útil y se hace referencia en MSDN como tablas de unión pura en ceder en un solo lugar):
Estudiante (studentID, ....)
de golf (courseid, ...)
tomando (studentID, courseid, grado)
Si alguien presenta un error de entrada de datos de un desplegable y pone a un estudiante en la clase equivocada, te gusta que cambien más tarde seleccionando la desplegable de nuevo y seleccionando un curso diferente. En el fondo, tendrá que eliminar el objeto EF de la tabla Toma y volver a crearlo sin perder una calificación, si es que hay una. Simplemente cambiando la clave externa CourseID parece una mejor alternativa. Propón tu propia asociación si esta parece artificial, pero como profesor fue natural para mí.
Conclusión: cuando tiene una cadena de relaciones, puede ser mejor no permitir la conexión en cascada y/o cambiar FK, pero existen escenarios razonables/lógicos donde 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 va a cambiar la propiedad de navegación o la propiedad clave en el modelo, respectivamente:
ha producido un referencial violación de restricción de integridad: Una propiedad clave principal que es una parte de restricción de integridad referencial no se puede cambiar cuando el objeto dependiente no se modifica a menos que se establezca en el objeto principal de la asociación. El objeto principal debe rastrearse y no marcarse para su eliminación.
La propiedad 'X' es parte de la información de la clave del objeto y no se puede modificar.
¿Puedo preguntar por qué quiere cambiar la clave principal? Eso es una muy mala práctica. –
Buena pregunta. Tenemos información anónima rastreada en la base de datos por su customerid anónimo. Cuando el usuario inicia sesión, quiero actualizar la tabla y configurarla para su customerid habitual. –
Solo yo, tendría dos tablas una para usuarios anónimos y luego, cuando inicien sesión, crearán un nuevo registro en la tabla principal, pero nunca modificarán la primaria. –