Linq To SQL y LINQ to Entities :: Usando campos autogenerados de SQL Server
Una de las particularidades de LINQ to SQL y LINQ to Entities es todo lo relativo a los metadatos. Es ahí donde recomiendo empezar a mirar cada vez que nos encontremos con un obstáculo o problema.
Muchos ya saben donde hay que ir a mirar la mayoría de las veces y que son realmente los metadatos cuando hablamos de LINQ to SQL o de LINQ to Entities, pero hay también mucha gente que desconoce todo esto y empieza a ponerse nerviosa cuando se encuentran un impedimento, y más aún cuando no está totalmente aclarado en ningún sitio y no encuentras nada en Internet al respecto.
Lo normal es encontrarnos con pequeños obstáculos como por ejemplo el que tiene que ver con los campos autogenerados de una base de datos, motivo de esta entrada, y que en este caso teórico tiene relación directa con SQL Server. Esto ocurre tanto en LINQ to SQL como en LINQ to Entities.
Supongamos por lo tanto, que partimos de un escenario en el que tenemos un modelo de base de datos que contiene una tabla con varios campos, y uno de ellos es un campo autogenerado. Hasta aquí lo normal. Si construimos una sentencia SQL de tipo Insert con ADO.NET tradicional, insertaremos una fila de datos en la tabla sin necesidad de indicar el campo autogenerado. Esto es así, porque SQL Server ya se encarga por nosotros de autogenerarlo con la información que hayamos indicado en la definición de la tabla de SQL Server.
Si en lugar de usar el tradicional ADO.NET utilizamos LINQ to SQL o LINQ to Entities, podremos agregar un nuevo registro a la base de datos de forma mucho más ágil y sencilla, sin embargo, a la hora de trabajar con la tabla indicada anteriormente y con una sentencia de tipo Insert, observamos que el campo autogererado es obviado y que en alguna parte de la aplicación, nos escribe en ese campo el valor que considera oportuno el modelo de datos de nuestro contexto (en un campo entero un 0 por ejemplo, etc).
La primera solución para resolver el problema es sencilla. Basta con indicar el campo de la entidad y su valor. Ahora bien, si es un campo autogenerado de la base de datos, es porque lo que nos permite precisamente es evitar indicar el valor del campo, algo que de esta manera quedamos obligados a hacer con el consiguiente problema añadido de mantenimiento de la base de datos y de filosofía de la aplicación y de la base de datos.
Mirando un poco más, encontramos una segunda solución mucho más limpia en cuanto a mantenimiento y en funcionalidad (recordemos que estamos hablando de un campo autogenerado que idealmente no deberíamos indicar jamás en el escenario indicado anteriormente).
Dentro de los metadatos, podemos hallar en el diseñador de entidades diferentes partes entre las que destacamos las entidades del modelo de datos, los metadatos de sus entidades (las tablas), y los metadatos de los miembros de cada entidad, o lo que es lo mismo, de cada una de las propiedades que conforman la entidad (los campos de las tablas).
También encontraremos más metadatos, pero fijémonos en estos en primer lugar para esta entrada.
Dentro de una entidad de tipo tabla, encontramos los campos a base de propiedades de la entidad.
Acudiendo al campo autogenerado en el modelo de base de datos, podemos encontrar diferentes propiedades.
Nos pararemos en la propiedad Auto Generated Value de LINQ to SQL.
Esta propiedad por defecto, vale False.
Si cambiamos este valor a True, podremos indicarle a la propiedad de la entidad que ese campo es autogenerado, por lo que será la base de datos la encargada de autogenerar el valor del campo por nosotros.
Ahora bien, ¿y en Entity Framework?.
Pues la verdad es que con LINQ to Entities está más rebuscado el tema que con LINQ to SQL (bastante más bajo mi punto de vista).
Mientras que con LINQ to SQL es relativamente fácil saber cómo abordar y resolver esta problemática, con LINQ to Entities lo he resuelto a través del archivo ssdl (Storage Metadata Schema) de los metadatos del modelo de datos.
Dentro del fichero ssdl (en formato XML) y en el apartado o etiqueta EntityType que indica la tabla, localizamos el campo autogenerado de la base de datos y le ponemos la siguiente instrucción: StoreGeneratedPattern=»Identity». También nos hubiera servido en nuestro ejemplo StoreGeneratedPattern=»Computed», pero como veremos en la explicación siguiente, esto lo deberemos indicar de acuerdo a nuestras necesidades.
La lista enumerada StoreGeneratedPattern pertenece al nombre de espacio System.Data.Metadata.Edm y al ensamblado System.Data.Entity.dll, y tiene tres posible valores: Computed, Identity y None.
Por defecto, los campos tienen el valor None, que equivale a que el valor no lo crea el servidor. Por esta razón, al insertar datos en una tabla con un campo autogenerado cuya propiedad StoreGeneratedPattern está indicada como None, el campo autogenerado es generado en el modelo de datos y enviado con su valor a la base de datos.
Identity es un valor generado en las inserciones que permanece igual en las actualizaciones.
Computed es un valor generado en las inserciones y en las actualizaciones.
De esta forma, vemos que los campos autogenerados son ignorados por defecto en LINQ to SQL y LINQ to Entities, y que si queremos salvaguardar la característica de ser un campo autogenerado, debemos indicárselo explícitamente.
El hecho de trabajar con campos autogenerados en una base de datos, es una de las características con la que nos presentaremos ante un proyecto LINQ to SQL o LINQ to Entities con más frecuencia.
Espero que estas explicaciones hayan servido para que alguien pierda menos tiempo con este tema o resuelva el entuerto en el que se encuentre de forma más ágil.
2 Responsesso far
Gracias. Me podeis decir como en una vista creo una tabla con un campo autogenerado¿?
Por favor
soy yo de nuevo, por favor me podeis decir como creo o le adjunto a una vista especificamente un campo autogenerado ¿?
Por favor es urgente