Integridad referencial de Linq a SQL sin base de datos

Estoy codificando una aplicación que usa una base de datos existente, esa base de datos tiene algunas tablas no puedo modificar nada, Sin embargo, puedo agregar nuevas tablas. Entonces, digamos que tengo una tabla antigua, Ciudades, en la que puedo leer, crear, actualizar y eliminar, pero no puedo modificar el esquema. Luego agrego una nueva tabla, Clientes, que tiene una clave externa a Ciudades, pero no puedo agregar una relación en el servidor de la base de datos (SQL SERVER 2008) ya que también modifica la tabla Ciudades, agregando una relación. Así que pensé que tal vez si agrego ambos a mi contexto linq-to-sql y agrego la relación allí, linq-to-sql sería lo suficientemente inteligente como para verificar la integridad referencial para mí, aunque la relación no está establecida en el base de datos, está en el contexto.

Creé un nuevo proyecto para probar eso, agregué dos tablas simples sin una relación, luego agregué la relación en el diseñador linq-to-sql e intenté forzar una excepción en la integridad referencial, pero parece que no funciona.

DBContextDataContext db = new DBContextDataContext();

City l = new City();
l.name= "Buenos Aires";
db.Cities.InsertOnSubmit(l);

Client c = new Client();
c.name = "Mike";
c.City = l;
db.Clients.InsertOnSubmit(c);

db.SubmitChanges(); // This works

db.Cities.DeleteOnSubmit(l); 
db.SubmitChanges(); // This shouldn't work, but it works

¿Alguna idea de si es posible forzar la integridad referencial? ¿O agregar la relación en el DB es la única forma?

preguntado el 12 de junio de 12 a las 21:06

Si puede agregar nuevas tablas, también puede agregar disparadores. Es una forma horrible de gestionar la integridad referencial, pero funcionará... -

Puedo agregar. Tal vez esa sea una solución... Necesito forzar esos errores, ya que heredé el sistema, y ​​ahora necesito mantenerlo, pero apenas verifica la integridad referencial y permite que el usuario elimine lo que quiera... Solo quiero asegurarme de que no rompa la integridad de la base de datos. -

@RaphaëlAlthaus Necesitaría un activador en la tabla a la que se hace referencia, Ciudades, para verificar que no existan Clientes al eliminar esa ciudad. Su premisa es que no puede modificar el esquema de Ciudades. -

¿Necesita "mantener el sistema", para que pueda modificarlo, pero no puede modificar la base de datos? ¿Significa eso que la base de datos no "pertenece" al sistema? En otras palabras, ¿otros sistemas también están modificando los datos? En ese caso, nada de lo que haga en el cliente impediría que esos otros sistemas modifiquen los datos (por ejemplo, eliminar una ciudad). Si es el propietario del sistema, incluida la base de datos, agregue la relación de clave externa. -

@KrisVandermotten tienes razón. Creo ... Pero eso no está tan claro: ¿cómo un FK que apunta a otro esquema "alteraría" ese esquema? Podría causar cambios en otras aplicaciones que apunten a este esquema ("¿por qué diablos no puedo eliminar esa ciudad?"), Claro, pero nada que ver con DB, ¿no? Si los derechos están bien... -

1 Respuestas

Puede anular el método SubmitChanges en DataContex y verificar los cambios realizados.

    public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
    {
        bool everythingIsOK = true;

        var changes = GetChangeSet();
        var inserts = changes.Inserts;
        var deletes = changes.Deletes;
        var updates = changes.Updates;

        //verify everything is valid
        //...

        //if you need to, you can get the original state of the updated objects like this:
        foreach(object x in updates) {
            var original = this.GetTable(x.GetType()).GetOriginalEntityState(x);
            //verify the change doesn't break anything
            //...
        }

        if(everythingIsOK){ base.SubmitChanges(failureMode); }
    }

Pero se siente doloroso. ¿Está absolutamente seguro de que no puede hablar con el DBA para realizar los cambios necesarios? Puede (supongo que también puede) agregar una tabla, pero no puede agregar una clave externa, por lo que la base de datos puede contener datos no válidos.

Además, si tiene que verificar los cambios de esta manera, eso significa que debe realizar más consultas a la base de datos para verificar que todas las claves, etc. sean válidas.

O esto ES definitivamente un truco:

  • Escriba el esquema de base de datos para usted mismo
  • Vuelva a crear la base de datos en su máquina, o donde quiera
  • Agregue las nuevas tablas y agregue claves externas a la base de datos
  • Genere el esquema linq desde su base de datos modificada local
  • Cambiar la cadena de conexión a la real

Y muy frágil: si algo cambia en la base de datos original, debe cambiarlo en su base de datos "ficticia" ...

Aún así, trate de razonar con su jefe, el DBA, o quien tomó esta decisión, porque no puede evitar que otra persona la elimine en la tabla a la que se hace referencia.

Respondido el 12 de junio de 12 a las 21:06

El problema es que la base de datos anterior es la base de datos de otro programa de 5 años súper probado y aún en desarrollo ENORME programa visual basic 6. Estoy escribiendo una extensión para ese programa, que se adapta a las necesidades del cliente. - gosukiwi

@gosukiwi sin una clave externa real, solo puede verificar sus propios cambios, pero si alguien de la otra aplicación elimina una ciudad, sus datos se rompen y otros usuarios ni siquiera lo notan. Simplemente no puedes hacer nada al respecto. - Akos Lukács

@gosukiwi ¿Y qué? ¿Es un requisito que el monstruo VB6 pueda eliminar ciudades, rompiendo así su código? De hecho, si todavía está en desarrollo, hable con esos desarrolladores y explíqueles que el código para eliminar ciudades debe estar preparado para recibir un error de la base de datos. - Kris Vandermotten

Ah, y mientras habla con ellos, mencione que VB6 no ha sido compatible como plataforma de desarrollo de Microsoft durante años... - Kris Vandermotten

Soy un poco nuevo aquí, y ellos lo saben, pero es lo que se usaba en ese momento, creo que podría tener incluso más de 5 años, OOP era tan nuevo que no se molestaron en usarlo cuando comenzó. piensa, y es uno de los programas más exitosos de la empresa. Sin embargo, hay un plan para ir a la nube con ASP.NET MVC. Supongo que tendré que verificar manualmente y esperar lo mejor, y muy buenos probadores. - gosukiwi

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.