none
Identity Columns y SQLCE para WP7 RRS feed

  • Debate general

  • Hola,
     
    Estoy tratando de encontrar la forma de poder configurar una columna ID que sea generada por SQLCE para WP7 (con el atributo IsGenerated=True) pero que tenga el siguiente comportamiento:
    + Si al añadir un nuevo objeto el valor de ID para ese objeto es null o 0 que le asigne el siguiente número según su contador interno.
    + Si el ID ya contiene un valor numérico superior a 0 se utilice como id del objeto en la bd el valor que trae.
     
    Yo de momento utilizando estos atributos no consigo que se respete el valor númerico que tenga asignado el ID del objeto añadido a la base de datos.
     [DbType = "Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, UpdateCheck = UpdateCheck.Never)]
    

     ¿Creeis que es posible hacer lo que quiero?
    Esto mismo es posible hacerlo en Sql Server con el comando:
    SET IDENTITY_INSERT dbo.TableName ON
    Sería interesante disponer de un atributo que permitiera hacer esto mismo a nivel de tabla/Entidad definida para SQLCE WP7
    Un saludo!


    viernes, 12 de agosto de 2011 10:07

Todas las respuestas

  • Hola Sergio,

    Te paso un link a un post de un compañero donde comenta que no se puede ejecutar TSQL en SQLCE y tu para ejecutar SET INDENTITY_INSERT necesitas eso.

     

    http://geeks.ms/blogs/jyeray/archive/2011/07/19/sql-server-ce-en-windows-phone-mango.aspx

     

    Saludos,


    phurtado
    sábado, 13 de agosto de 2011 16:55
  • Buenas!

    Bueno, existen situaciones y situaciones... pero NUNCA he visto usar IDENTITY_INSERT en una aplicación con código real, principalmente porque es un peligro brutal de obtener colisiones de clave primaria... lo normal es usar IDENTITY_INSERT para generar datos genéricos en la base de datos mediante un script de post deployment, ejecutado despues de crear la base de datos.

    No sep... yo creo que no es necesario, incluso es mejor no tenerlo y así no caer en la tentación de usarlo y ya te digo que nunca lo he usado ni visto usarlo en código de producción...

    Un saludo!


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    domingo, 14 de agosto de 2011 13:59
    Moderador
  • Perdón por responder tan tarde, estoy de vacaciones y no me he conectado mucho a internet.

    Josue estoy de acuerdo en que hay peligro de colisión de claves primarias, pero esto es un riesgo que hay que gestionar siempre que quieras tener claves únicas o primarias que puedan ser decididas por el usuario en lugar de por la bd en determinados momentos.

    Si no puedo utilizar claves identidad asignadas por el usuario tendré que usar como siempre he hecho una clave primaria no identidad que yo incremente automáticamente basandome en un contador que guardaré en otra tabla cuando el usuario no me proporcione un valor. El problema es que WP7 hasta donde yo se no soporta transacciones a nivel de bd (si a ni a nivel de UoW) para hacer estas operaciones de forma atómica en bd. En la práctica no debería haber problema pero mis accesos a bd son asíncronos luego en teoría debería de hacer todo en la misma transacción: obtener el siguiente código e incrementarlo y el insert.

    Pero eso si tanto para lo que proponía en mi pregunta como en esta solución alternativa si el usuario introduce una clave repetida mi aplicación debe gestionar esa colisión invitando al usuario a utilizar una clave que no exista para hacer la inserción en la bd.

    Otra cosa es que SQL Server tenga problemas para devolver un id válido una vez su contador interno para columnas identidad llegue a un valor para el cual el usuario ya haya introducido un registro con ese valor como clave ¿es ese el peligro brutal al que te refieres?. No se si esto es así o no pero si fuera así entiendo que SQL Server debería ser capaz de por si sólo ir incrementando su contador interno hasta llegar a un valor para el cual no existan registros en la bd.  

     

    Un saludo y muchas gracias por vuestras respuestas

    domingo, 21 de agosto de 2011 18:26
  • Hola Sergio,

    Me alegro que estés de vacaciones, eso siempre es buena cosa. Pero voy a dejar que el amigo Yosue te responsa, yo ya te digo estas equivocado :)

     

    Saludos,


    phurtado
    domingo, 21 de agosto de 2011 20:52
  • Hola Sergio.

    A ver, yo nunca permitiria a un usuario indicar directamente la clave primaria de mi tabla, para mi, esta columna identidad, es de uso interno. ¿Por Que? Pongamos un ejemplo:

    Tenemos una tabla de artículos: Codigo, nombre, descripción, precio... En este caso, codigo, necesita ser alfanumérico, porque puede llegar "cualquier cosa" a ese campo y es el usuario el que lo especifica. Bien, en este caso, yo dejaria la tabla así: Id, codigo, nombre, descripcion, precio... ¿Id y Codigo son lo mismo? NO de ninguna manera, el campo Id es un campo identidad, clave primaria de mi tabla que usaré para las relaciones con otras tablas, por ejemplo a la hora de relacionar articulos con lineasPedido, usaré el Id de cada artículo, porque un campo numérico es muchisimo más rapido para trabajar y relacionar, ademas de más pequelo, que un campo cadena como código, y porque código es un campo de mi usuario, que puede editar cuando le venga en gana, pero haga lo que haga, el artículo Id 615, relacionado en el ticket id 45 y 59, siempre será el id 615, sea su codigo art001 o 430012300032. A mi no me importa lo que el usuario edite en sus campos, pero mis relaciones, no las puede tocar, por que uso un campo identidad para ellas.

    El peligro brutal al que me refiero es que el usuario especifique un valor de campo que ya exista, o que todavía no exista y pueda darse el caso de que SQL Server colisione con ese valor. o que quiera editar un valor ya guardado, tendrias que ir por todas las tablas relacionadas ajustando el valor editado.

    Ya te digo, para mi, la columna identidad de una tabla es un valor interno, que sirve como distinción entre registros, para relaciones entre tablas y que no debe poder ser alterado por el usuario.

    Un saludo :)


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    lunes, 22 de agosto de 2011 4:44
    Moderador
  • Entiendo Josue. El caso de entidades que utilizan claves primarias alfanuméricas lo resuelvo tal como indicas. El problema es que esto me genera dos problemas:

    + Las consultas a la labla lineasVenta que sólo requieren la referencia requieren de un INNER JOIN a producto sólo para obtener la referencia.

    + Para la gente del servicio de atención al cliente que tiene que urgar en ciertos momentos en la base de datos es poco práctico tener que lidiar con el idCodigo de un producto en todas las tablas que referencian a un producto, cuando lo que les interesa es la referencia.

    Para aliviar estos problemas en las lineasVenta incluyo tanto el campo código del producto como el campo referencia. Ambas propiedades son de sólo lectura. De manera que sus variables privadas correspondientes sólo se actualizan cuando a la entidad de dominio LineasVenta se le asigna un producto. 

    Para evitar problemas incongruencias en la bd no permito modificar la referencia de un producto una vez dado de alta.

    Esta estratégia basada en redundancia de información es poco deseable de ahí que quiera reducir su uso y a la vez no caer en los problemas que he comentado cuando sea posible. Por eso cuando tengo entidades para las cuales su id y su clave podría perfectamente tener el mismo valor y que además no permito la modificación de su clave/id una vez añadidos (sólo la eliminación de la entidad o la modificación de otros datos), entiendo que en ese caso (que es para la mayoria de mis entidades) puedo usar el mismo id como clave.

    De esta frase hay un punto que no entiendo ( he quitado el "o" para referirme exactamente al caso que no veo claro) :

    El peligro brutal al que me refiero es que el usuario especifique un valor que todavía no exista ..... y pueda darse el caso de que SQL Server colisione con ese valor

     En cuanto al tema de editar el valor del id tienes toda la razón, yo evito ese problema no permitiendo al usuario modificar el id una vez agregada una entidad.

    . o que quiera editar un valor ya guardado, tendrias que ir por todas las tablas relacionadas ajustando el valor editado.

    ¿En vuestra opinión los problemas que indico no justifican usar estas soluciones?

    Aun así usando la estrategia de tener una clave y un id diferentes ¿como solucionas el hecho de que haya que  asignarle a la clave un valor numérico incremental y único cuando el usuario no lo facilite si no tienes disponible transacciones para gestionar un contador en otra tabla?

    Muchas muchas gracias por el feedback :)


    lunes, 22 de agosto de 2011 10:29