Problemas y soluciones: Entity Framework, vistas y claves

Uno de los grandes problemas que me he encontrado a la hora de trabajar con Entity Framework (EF) es la de mapear una vista.

¿Dónde está el problema?

El problema está que una entidad de EF debe tener una clave primaria y las vistas no tienen claves primarias.

image

En una vista como la anterior realmente no tenemos una clave definida en la base de datos ya que los datos filtrados por Entidad generaría una gráfica como la siguiente:

image

Por defecto EF infiere que Entidad es una clave, lo infiere a partir de aquellos campos que SQL Server dice que no pueden ser nulos. En principio no da ningún problema, pero tenemos dos casos en los que ya encontramos conflictos.

  1. Obtenemos más de un resultado con Entidad idéntica. Al rellenar los objetos EF, presupone que al tener la misma clave primaria son el mismo objeto por lo que siempre tendríamos el primer objeto creado.
  2. Si filtramos por Entidad exclusivamente, EF presupone que solo vendrá un resultado por lo tanto se produce una excepción.

Hasta aquí bien, la solución podría ser quitar esa clave, EF no nos deja:

“Toda entidad tiene que tener una clave primaria”

¿Solución?

Para ello debemos de crear una clave artificial, el rowcount de nuestra vista puede ser una opción, ya que todas las claves deben ser distintas. Pero como aun así nuestro Entity Framework no lo detecta como clave debemos emergernos en el EDMX y modificar el XML a mano.

Para ello cabe destacar que el fichero XML tiene un elemento llamado <edmx:Runtime> que es el que a nosotros nos interesa y que éste consta de tres partes:

  1. SSDL: StorageModels: El modelo importado de la base de datos
  2. CSDL: ConceptualModels: El modelo generado a partir del importado y el que representará cada una de las entidades que luego usaremos por código
  3. C-S: Mappings: Es la que une ambos modelos

Nosotros primero debemos modificar el SSDL, el siguiente es el :

<EntityType Name="vXXXX">
  <Key
    <PropertyRef Name="Entidad" /> 
  </Key
  <Property Name="IDPK" Type="bigint" /> 
  <Property Name="Entidad" Type="int" Nullable="false" /> 
  <Property Name="FechaPrevista" Type="datetime" /> 
  <Property Name="Sobres" Type="int" />
</EntityType>

Este sería el modelo importado tal cual lo importó el diseñador. Como veis hemos creado el campo IDPK con el rowcount para establecerlo como clave. Para poder hacerlo se debe de hacer lo siguiente:

 

<EntityType Name="vXXXX"
  <Key
    <PropertyRef Name="IDPK" /> 
  </Key
  <Property Name="IDPK" Type="bigint" Nullable="false" /> 
  <Property Name="Entidad" Type="int" /> 
  <Property Name="FechaPrevista" Type="datetime" />
  <Property Name="Sobres" Type="int" />
</EntityType>

Entonces en el modelo de la base de datos ya tenemos IDPK como clave. Ahora solo nos queda cambiarlo en el diseñador. Y para ello debemos hacer click derecho en el campo y establecerlo como clave:

image 

Y así ya podremos trabajar normalmente con nuestra entidad.

Problemas posteriores

Problemas tendremos después cuando actualicemos el modelo desde la base de datos, porque el SSDL se modificará y tendremos que hacer a mano los cambios que ahora hemos hecho. En cambio en el diseñador no tendremos que hacer nada.

Un comentario en “Problemas y soluciones: Entity Framework, vistas y claves”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *