2010-03-19 10 views
15

Tengo una base de datos SQLite que está configurada para que cuando elimine una persona, la eliminación se realice en cascada. Esto funciona bien cuando elimino manualmente una Persona (se borran todos los registros que hacen referencia a PersonID). Pero cuando se utiliza Entity Framework para borrar la persona consigo un error:Problema con la eliminación en cascada utilizando Entity Framework y System.Data.SQLite

System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

No entiendo por qué esto está ocurriendo. Mi desencadenador está configurado para limpiar todos los objetos relacionados antes de eliminar el objeto que se le dijo que elimine.

Cuando voy al editor de modelos y compruebo las propiedades de la relación, no muestra ninguna acción para la propiedad OnDelete. ¿Por qué no está configurado correctamente sacándolo del DB? Si cambio este valor a Cascade, todo funciona correctamente, pero prefiero no confiar en este cambio manual, porque si lo hago, renuevo mi modelo desde el DB y lo pierde.

Aquí está el SQL revivido para mis tablas.

CREATE TABLE [SomeTable] 
(
    [SomeTableID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
    [PersonID] INTEGER NOT NULL REFERENCES [Person](PersonID) ON DELETE CASCADE 
) 
CREATE TABLE [Person] 
(
    [PersonID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT 
) 

Respuesta

24

Acabo de resolver este problema exacto. Resultó que cuando utilicé EF a la opción Update model from database..., no obtenía correctamente la regla "Cascada" para borrar.

Intente ir a su modelo de base de datos EF, haga clic en la asociación que está causando el problema, luego asegúrese de que el End1 OnDelete (podría ser End2, depende del esquema de base de datos) está configurado en Cascade.

+0

¿Hay alguna manera de averiguar si debe actualizar End1 o End2? ¿O solo es prueba y error? –

+1

Depende de la forma en que se modele su base de datos.Si tiene una relación de uno a varios, el extremo 'uno' debe establecerse en 'Cascade' – Omar

1

Me parece un error de proveedor. La cascada debe recogerse del DB. Pruébalo con SQL Server; verás que funciona allí. Debe informar esto a quien haya escrito su proveedor de SQLite.

+0

Puedo verificar que no es (solo) un error del proveedor de SQLite. Agregar cascadas no se refleja en el modelo en SQL Server a menos que elimine todo el modelo y vuelva a crear. Dolor. – Andiih

+0

@Andiih, solo si la entidad se ha agregado sin ellos (presumiblemente incorrectamente) en primer lugar. El diseñador no sobrescribe su CSDL personalizado. Esa es en realidad una característica. –

+0

Sí, me equivoqué en el diseño de la base de datos. No había personalizado el CSDL. ¿Hay alguna forma de forzar una actualización sin eliminar y volver a agregar todo el modelo? – Andiih

4

Estaba teniendo el mismo problema con SQL Server. Cuando traté de actualizar el modo desde la base de datos, no recogió las reglas de la cascada. Tenga en cuenta que las reglas se agregaron después de que el modelo ya se haya creado. Incluso traté de eliminar una tabla del modelo y volver a agregarla. Eso tuvo el mismo efecto: no reglas en cascada.

Sin embargo, cuando creé un nuevo modelo con las mismas tablas exactas, recogió las reglas de la cascada. Así que mi solución fue simplemente eliminar el modelo anterior y crear uno nuevo con el mismo nombre, etc.

Supongo que hay algo mal con el modelo de actualización del proceso de la base de datos.

+1

Tuve este mismo problema con el servidor Sql –

+1

También puedo confirmar el mismo problema – Andiih

+0

El diseñador nunca sobrescribirá el CSDL existente. Porque generalmente desea mantener sus personalizaciones. En este caso, no es así, pero ese no es el caso común. –

0

Puede usar la propiedad de navegación solamente sin utilizar la propiedad de clave externa. La cascada de eliminación no resuelve el problema en el código porque su objeto personal no se marcará como eliminado.

Cuestiones relacionadas