Este error se produce cuanto trabajamos con pre-generated views en Entity Framework.
Este Post describe una forma de solucionar este error.
En el caso en particular que describo este es el escenario:
Base de Datos: Oracle, con distintos esquemas en función de cada entorno.
Proveedor de Datos: Devart
ORM: Entity Framework 4
Generación de pre-generated views: Mediante la plantilla T4
Entorno de compilación: Visual Studio Team Foundation Server 2010 Service Pack 1
Arquitectura: Proyecto basado en DDD utilizando la arquitectura n-layered de Codeplex.
El error se produce al desplegar una versión tras realizar una build en el TFS apuntando a un nuevo esquema de base de datos, cambio que realiza la propia build con una custom activity sobre el fichero .edmx antes de compilar.
Pregenerated Views
Las pregenerated-views aportan una gran reducción de tiempo en proyectos que utilicen Entity Framework.
La referencia a estas mejoras se pueden encontrar aquí:
http://msdn.microsoft.com/en-us/library/bb896240%28v=vs.90%29.aspx
El Problema
El error se produce por no ejecutar la plantilla T4 para regenerar las vistas después de haber modificado el fichero .edmx. Cuando se ejecuta la plantilla .tt mediante Run Custom Tool se genera un fichero .cs que incluye unas hash que Entity Framework utiliza para ver si ha variado la información de las vistas.
Esta hash se encuentra en el fichero .cs generado por la plantilla .tt
- namespace Edm_EntityMappingGeneratedViews
- {
-
-
- /// <Summary>
- /// The type contains views for EntitySets and AssociationSets that were generated at design time.
- /// </Summary>
- [System.Diagnostics.DebuggerNonUserCode()][System.CodeDom.Compiler.GeneratedCode(«EF»,«v 4.0»)]public sealed class ViewsForBaseEntitySetsD8764C9409F9061FB3ACFF9A2D927400C418BCF91616A573FD109E312323984A : System.Data.Mapping.EntityViewContainer
- {
-
- /// <Summary>
- /// The constructor stores the views for the extents and also the hash values generated based on the metadata and mapping closure and views.
- /// </Summary>
- public ViewsForBaseEntitySetsD8764C9409F9061FB3ACFF9A2D927400C418BCF91616A573FD109E312323984A()
- {
- this.EdmEntityContainerName = «EntitiesMant2»;
- this.StoreEntityContainerName = «MantStoreContainer»;
- this.HashOverMappingClosure = «b259ca6b447b5503d17e29d1089b9731f467487917f28b6e80b3ef67a296e833»;
- this.HashOverAllExtentViews = «576048e78b6e27609be586140ddb9e3dc2abdc665cf47ddc76534fc80c15a8b9»;
- this.ViewCount = 28;
- }
El hash se genera en base al contenido del fichero .edmx con lo que cualquier cambio que hagamos en él dejara el hash invalidado y por lo tanto tendremos problemas.
Siguiendo la información reportada en el blog de Oleg Sych:
http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/#comment-3483
Y su referencia en MSDN
http://msdn.microsoft.com/en-us/library/ee847423.aspx
Encontré la solución que describo a continuación.
Resolución del Error
Para resolver el error es necesario:
Que todos los desarrolladores y en el servidor en el que hacemos la build, tengamos instalado:
Visual Studio 2010 SDK
Visual Studio 2010 Visualization & Modeling SDK
Una vez descargados modificaremos el fichero de proyecto (.csproj) que contiene el .edmx y la plantilla .tt, haciendo un unload y editándolo, agregando las siguientes entradas:
Fichero .csproj
- <Import Project=«$(MSBuildExtensionsPath)MicrosoftVisualStudioTextTemplatingv10.0Microsoft.TextTemplating.targets« />
- <PropertyGroup>
- <TransformOnBuild>false</TransformOnBuild>
- <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
- <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
- <!– Other properties can be inserted here –>
- </PropertyGroup>
- <PropertyGroup>
- <PreBuildEvent>«%25windir%25Microsoft.NETFrameworkv4.0.30319msbuild.exe» $(ProjectDir)Infrastructure.Data.proyecto.csproj /t:Transform /p:TransformFile=ModelDPTCampaignMant.proyecto.tt</PreBuildEvent>
- </PropertyGroup>
Con estas entradas y el prebuildEvent conseguiremos que se ejecute la plantilla .tt volviendo a generar las vistas y cambiando los hash justo antes de que se ejecute la compilación.