Ir al contenido principal

Cómo determinar la clave primaria en una entidad con Entity Framework y Data Annotations

Con Entity Framework 4.1, a las opciones del modelo primero (Model First) y base de datos primero (Database First), se añadió Code First. Con esta aproximación, el programador escribe clases (objetos POCO) para cada una de las entidades que quiere manejar en su aplicación. Estas entidades pueden generar tablas en una nueva base de datos o ser mapeadas a una base de datos ya existente.

En general, EF usa una serie de convenciones para definir el modelo y mapearlo a la base de datos de forma automática. Por ejemplo, Entity Framework puede reconocer automáticamente el campo que es clave primaria de una tabla si éste se llama de la forma NombreTablaId

El problema.


Supongamos que estamos desarrollando una nueva aplicación para una colección de discos. Se trata de una aplicación web, que estamos programando con la arquitectura MVC. Si en ella tenemos una tabla que se llama Disco, EF espera que el campo que sea clave primaria de la tabla se llame DiscoId. De no ser así, cuando intentemos crear, por ejemplo, el controlador para el modelo Disco, obtendremos el siguiente error:

Visual Studio nos dice que hay un error de validación en el modelo. Discography no tiene clave definida.
Si estamos creando una base de datos nueva, puede que lo más sencillo sea cambiar el nombre de nuestro campo clave primaria para adaptarlo a las necesidades del Entity Framework. Sin embargo, si nuestra clave es una clave compuesta o estamos trabajando sobre una base de datos ya existente sobre la que no tenemos la posibilidad de cambiar el nombre de los campos, necesitamos una alternativa.

La solución.


Aquí es donde las Data Annotations vienen al rescate: Podemos indicarle a las propiedades de nuestra
entidad (nuestro modelo) ciertas características que lo definen mejor, para que Entity Framework comprenda correctamente cómo está definida. Una de ellas es la propiedad KeyAttribute, representada como [Key]. Así le podemos decir al EF cuál de las columnas de nuestro objeto POCO es la que ejerce de clave primaria:
[Key]
public int TableKey { get; set; }
Si, además la clave primaria es compuesta, tenemos también solución: debemos indicar el atributo Key a todas las columnas que forman parte de la clave primara, indicando el orden de éstas en la misma, de la siguiente manera:

[Key]
[Column(" TableKey1", Order = 0)]
public int TableKey1  { get; set; }
[Key]
[Column(" TableKey2", Order = 1)]
public int TableKey2  { get; set; }

Si hemos instalado las Entity Framework Power Tools (recomendable, aunque todavía en fase Beta), podremos ver cómo queda nuestro modelo tras realizar estas anotaciones (mediante clic derecho sobre el fichero contexto y eligiendo en el menú la opción Entity Framework / View Entity Data Model):
Diagrama de nuestra entidad Disco, con los dos campos formando parte de la clave primaria.

Data Annotations vs Fluent API.


Existe una alternativa a las Data Annotations, llamada Fluent API, que veremos más adelante. Data Annotations presenta una manera más sencilla de configurar el modelo, mientras que Fluent API ofrece más posibilidades. Además, las Data Annotations son usadas al mismo tiempo por Entity Framework y por MVC, para validar los datos que el usuario introduce en las vistas (páginas web). Sin embargo, es posible que si nuestro modelo es ligeramente complejo, necesitemos de la potencia de Fluent API.

Puedes leer más acerca de Data Annotations y Fluent API aquí.

Puedes encontrar más información acerca de las anotaciones en:

Comentarios

Entradas populares de este blog

Aprendiendo a usar LEFT OUTER JOIN

En esta entrada pretendemos explicar los diferentes resultados obtenidos por distintas construcciones de consultas que, aparentemente, deberían producir el mismo conjunto de resultados. Así, veremos las diferencias entre filtrar los resultados de una query en la unión (Join) mediante condiciones ON y mediante cláusulas WHERE.

Variantes del SELECT COUNT con DISTINCT

Seguramente, muchos de vosotros habréis usado en innumerables ocasiones la función de T-SQL COUNT , que no hace sino devolver un número de registros: de una tabla, de un conjunto de resultados, etc... En una de sus aplicaciones, combinado con el DISTINCT -uno de los dos argumentos que admite- COUNT nos devuelve el número de valores únicos no nulos de la tabla o conjunto de resultados que estemos consultando. Pero ¡ojo! Cuidado con la sintaxis , o podemos obtener el valor equivocado sin darnos cuenta. No es lo mismo: SELECT COUNT (DISTINCT NombreCampo) FROM NombreTabla que: SELECT COUNT(*), DISTINCT NombreCampo FROM NombreTabla

Script para obtener el tamaño de todas las tablas de la base de datos

En algunas ocasiones podemos vernos con la necesidad de conocer qué tablas de nuestra base de datos están ocupando más espacio en disco. Por ejemplo, si disponemos de SQL Server Express , cuyas bases de datos están limitadas a 4GB o 10GB, según la versión que estemos usando -4, hasta 2005; 10, a partir de 2008-, aparte de usar las opciones de comprimir la base de datos, poner el log en el modo simple de recuperación o ajustar las políticas de crecimiento automático de nuestros ficheros, podemos necesitar averiguar qué tablas crecen más para tomar las decisiones oportunas.