domingo, 16 de diciembre de 2012

funciones Lazy en c#, o ejecución de funciones perezosas


En alguna ocasión puede que os haga falta definir una llamada a una función, y ejecutarla en otro momento de la aplicación. (Cachés, funciones con muchos bucles,  etc.)

En .NET 4.0, la clase Lazy permite hacer esto.
Según el MSDN,  se utiliza una instancia de Lazy<T> para diferir la creación de un objeto grande o con uso intensivo de recursos, o la ejecución de una tarea con uso intensivo de recursos, especialmente cuando puede que no se produzca esa creación o ejecución durante la duración del programa.

Veamos un ejemplo , que es donde mejor se ve.

        static void Main(string[] args)
        {
            Lazy<int> fn= new Lazy<int>(()=>Sumar(3,4));
            Console.WriteLine("Función definida, pero no ejecutada");
            Console.WriteLine("Valor creado: "+ fn.IsValueCreated);
            Console.WriteLine("Valor: "+ fn.Value);
            Console.WriteLine("Valor creado: "fn.IsValueCreated);
        }

        public static int Sumar(int a, int b)
        {
            return a + b;
        }

 Definimos fn como una llamada a Sumar (3, 4) , pero no se procesa hasta que no se llame a fn.value.

Si copiáis el código en el VS y depuráis, lo veréis mejor.

Saludos.



lunes, 1 de octubre de 2012

Diagrama de tablas en Ax2012

Hola.

Estamos "lidiando" con la estructura de tablas y las relaciones que tiene el nuevo AX2012.

La teoría y la recomendación es que no se acceda a las tablas directamente, ya que hay unas opciones muy válidas para integrar aplicaciones en Ax2012 como Interop, AIF y Business Connector

Pero si necesitáis atacar a las tablas directamente, no queda otra que comprender su estructura.
Para ello, comparto (con permiso de mis compañeros), los diagramas de relaciones de los módulos que hemos ido necesitando.

Nombres y direcciones

Como sabéis, en AX2012 se ha creado un AddressBook que ha normalizado todos los nombres y direcciones en tablas relacionadas. Este es el diagrama que relaciona estas tablas:

Tablas que intervienen:

Vistas que intervienen:

  • DirPartyContactInfoView (Enlace )
  • DirPartyPostalAddressView (Enlace )
  • DirPartyNameView (Enlace )

Dimensiones

Tablas que intervienen:

  • DimensionAttributeValue (Enlace )
  • DimensionAttributeValueSetItem (Enlace )
  • DimensionAttribute (Enlace )

Vistas que intervienen:

  • DefaultDimensionView (Enlace )

Personal, trabajadores y roles de proyecto

Tablas que intervienen:



Cuentas Contables (antigua LedgerTable)


Tablas que intervienen:

  • MainAccount (Enlace )
  • MainAccountLegalEntity (Enlace )
  • DimensionAttribute (Enlace)
  • DimensionAttributeValue (Enlace)
  • DimensionAttributeValueCombination (Enlace)
  • DimensionAttributeValueFinancialStmt (Enlace)


Diarios (antigua LedgerTrans)


 Tablas que intervienen:


  • LedgerEntryJournal (Enlace )
  • GeneralJournalEntry (Enlace )
  • SubledgerVoucherGeneralJournalEntry (Enlace )
  • FiscalCalendarPeriod (Enlace )
  • LedgerEntryJournalizing (Enlace)
  • GeneralJournalAccountEntry (Enlace)
  • LedgerEntry (Enlace )
  • TaxTransGeneralJournalAccountEntry (Enlace)
  • TaxTrans (Enlace )
  • DimensionAttributeValueCombination (Enlace )






De momento esto es todo. Si van surgiendo nuevos diagramas los iré subiendo.
Y si la entrada te ha sido de utilidad, pincha en la publicidad para que Google me financie algún café al año. ¡Gracias por adelantado!
Saludos!!!







martes, 18 de septiembre de 2012

Tipos de integración VS2010 - AX 2012


Con motivo de la integración de nuestras aplicaciones .NET con Microsoft Dynamics AX 2012, he ido resumiendo la información que he ido leyendo y probando.

AX2012 proporciona las siguientes formas de integrarse con aplicaciones:


Managed Interop o Proxy Classes.


http://msdn.microsoft.com/en-us/library/gg879799


http://msdn.microsoft.com/EN-US/library/gg889166


 Te permite acceder a las Clases, Tablas y Enums del AOT (Application Object Tree) de Ax2012 desde Visual Studio a través de Proxys, así como ver datos de display, métodos, etc... directamente, por lo que tienes un acceso a ALTO NIVEL a los objetos de Axapta.

Este método de acceso, comparado con el Business Connector, tiene la ventaja de tener Intellisense de las clases, tablas y enums que vas manejando, así como la detección de errores por parte del compilador, al ser objetos tipados.

Aquí recomiendo la consulta de “Tips de integración AX2012” si surge algún error.

Pasos para usar Interop:

  • Nos creamos un nuevo proyecto en Visual Studio 2010 (en un equipo que tengamos instalado AX2012 con las Developer Tools)
  • En el proyecto que vayamos a acceder a Ax, creamos una referencia a Microsoft.Dynamics.AX.ManagedInterop que se ubica en “C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin”
  • Botón derecho en el proyecto en el “explorador de soluciones” -> Add Project1 to AOT. 
  • Se nos habrá creado una ventana “Application explorer” (que la podemos sacar de Ver > Application Explorer) en la que tenemos el AOT de AX2012.








  • Elegimos los objetos con los que queremos interactuar del AOT (recuerda: Tablas, clases y enumerados) y los arrastramos al árbol de proyecto en el Explorador de Soluciones de VS2010. Esto nos creará unos proxys con los que podremos trabajar
  •  Usaremos los proxys
Un ejemplo de uso:









Fijaos en el consumo de VendTable. VendTable es el proxy que se ha generado al arrastrar la tabla al árbol de proyecto.  Estamos usando el método FindByCompany, y luego estamos recuperando la información de forma tipada, con Intellisense, e incluso, pudiendo llamar a Displays y métoodos. 


Business Connector for .NET


NOTA: Se recomiendan los otros tipos de integración, ya que este método se mantiene por compatibilidad con anteriores desarrollos, y no se garantiza su continuidad en futuras versiones. 

Es otro componente que permite accede a los elementos del AOT, pero sin tener proxys ni tipos, y llamando directamente a sus métodos y propiedades.

Ataca un nivel más bajo que los proxyes de Interop, ya que los campos display y los métodos hay que llamarlos mediante Call() y no aparecen integrados dentro de la llamada principal.

Vuelvo a hacer referencia a  “Tips de integración AX2012” por si surge algún error.

Pasos para usar Business Connector.

Son unos pasos parecidos al Managed Interop.
  •  Nos creamos una solución en Visual Studio 2010 (en un equipo que tengamos instalado AX2012 con las Developer Tools)
  • En el proyecto que vayamos a acceder a Ax, creamos una referencia a Microsoft.Dynamics.BusinessConnectorNet.dll que se ubica en “C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin”
  • Botón derecho en el proyecto en el “explorador de soluciones” -> Add Project1 to AOT.
  • Creamos el código.

Si habéis trabajado con el AxaptaComConnector de la versión 3, esto os recordará su manejo.

También fijaos que los Displays Name y Email hay que llamarlos. En el proxy generado de Managed Interop, estas llamadas estan incluidas en el proxy, por lo que el código resultante es más compacto.
Application Integration Framework (AIF)

http://axwonders.blogspot.com.es/2012/01/microsoft-dynamics-ax-2012-services-and.html

El AIF es una plataforma que permite interactuar con cualquier aplicación, ya sea .Net o de otro tipo, ya que la comunicación se basa en WCF.

Algunos de estos servicios se pueden publicar en el AOS (Application Object Server) o en el IIS.
Por buscar símiles, el IIS expone servicios WCF y el AOS expone los servicios AX2012

El AIF se compone de:
  • Document Services
  • Custom Services
  • System Services

Document Services
Su símil con WCF sería el Contract; o sea, el objeto que se expone al servicio. Se trata de una query autogenerada (query con prefijo AXD ) a partir de una entidad determinada. Microsoft ya ha creado unos 70 documents de las entidades más representativas, a falta de exponerlos en el AIF.

Los campos DEL_ de las tablas y los campos con la propiedad "Visible=false" no son incluidos en el documento.

En el caso de que quisiéramos crear nosotros nuestro propio document Service , se puede seguir el siguiente walkthrough


Pasos para crear un Document Service.

  • Creamos la Query (o buscamos la query AXD ya generada que nos cuadre)
  • Creamos el servicio basándonos en la query (Espacio de desarrollo > herramientas > Marco de integración de la aplicación > Crear servicio de documentos), eligiendo los métodos que queremos que nos autogenere (Read, Write, Find...)

  • Este paso generará una clase con prefijo AXD y un servicio ya preconfigurado con los métodos que hemos elegido.
  • Nos quedará publicarlo; para ello vamos a Service Groups, creamos un nuevo Service Group y añadimos un nuevo nodo por cada servicio que queramos añadir en el Service Group. En propiedades de cada nodo vamos eligiendo el Service que queremos publicar.
  • Una vez tengamos todo el Service Group completo, implementaremos.
  • Para ver que el servicio está correctamente publicado, lo podremos ver en el espacio de trabajo > Administracion del sistema > Configurar > Services and Application Integration Framework > Puertos de entrada.


Esto te crea un nuevo servicio de tipo "Base" que es creado con una configuración por defecto. Si queremos configurar el adaptador y poder ajustar más opciones, en esa misma pantalla podríamos eliminar y crear un nuevo puerto de entrada, que sería de modo extendido, y permitiría configurar todos los parámetros posibles (configurar el Binding del WCF)
Más info en
http://msdn.microsoft.com/en-us/library/aa609947

Tipos de puertos 

Ya que hemos tocado los puertos, decir que los InboundPorts reciben peticiones desde fuera de AX y los Outbound ports emiten peticiones a otros sistemas.

Consumo de un Document Service

En Visual Studio 2010, nos creamos una referencia de servicio a la dirección que aparece en la imagen superior, en el campo "uri de WSDL"

aquí os pongo un ejemplo de cómo se haría un "read" de un proveedor.


Custom Services

Son unos servicios más flexibles y personalizados que los Document Services, ya que permiten exponer directamente una clase a un servicio, que es lo que hacemos normalmente con WCF.

Pasos para crear un Custom Service.

  • En el AOT, creamos nueva clase
  • Añadimos métodos decorándolos con atributos correctamente. [SysEntryPointAttribute(true), AifCollectionTypeAttribute('return', Types::String)]
  • Creamos un nuevo service, y lo mapeamos a la clase (propiedad class).
  • Dentro de Servicios, en el árbol Operaciones, añadimos las operaciones(seleccionamos los métodos que hemos creado)
  • Creamos un nuevo grupo de servicio, y añadimos nuevos serviceNodeReference asociados a services.
  • Publicamos
Como anteriormente hemos comentado, para ver que el servicio está correctamente publicado, lo podremos ver en el espacio de trabajo > Administracion del sistema > Configurar > Services and Application Integration Framework > Puertos de entrada.

Consumo de un Custom Service

Lo consumiremos como como un servicio normal, creando un Service Reference (que ya hemos visto en los Document Services)





Estos métodos devuelven tipos básicos. Si queremos que devuelva tipos complejos (clases de datos) , usaremos los DataContracts, como en WCF
Para ello, creamos una clase contenedora de datos y la etiquetamos como [DataContractAttribute], s métodos los etiquetando los métodos con [DataMemberAttribute('XXX')]
Más info en:

http://sumitsaxfactor.wordpress.com/2012/06/13/data-contracts-and-custom-services-ax-2012/

System Services


Solo AOS sobre TCP. Usado para recibir metadatos, datos de una query o información de usuario.
Los system services son un conjunto de los siguientes servicios:
  • Query Services
  • Dynamic Query
  • User-session Services
http://msdn.microsoft.com/en-us/library/gg879657.aspx

Query Services

Expone el AOT para realizarle queries. Devuelve datasets. La url es net.tcp://<hostname:port>/DynamicsAX/Services/QueryService

El llamador necesita tener los permisos apropiados para recoger la información.
Se componen de:
  • Static query
  • User-Defined query
  • Dynamic Query
http://msdn.microsoft.com/EN-US/library/gg847959.aspx

Static Query

Query que ha sido definida previamente en el AOT.

http://msdn.microsoft.com/en-us/library/gg863932.aspx

User-defined query

Query definida usando la clase QueryMetaData del MetadataService

Dynamic Query

(Ejemplo: buscar clase KanbanOverviewJobsQueryBuilder)
Query definida en una clase X++ que hereda de AIFQueryBuilder, implementándose en el método Initialize

    QueryServiceClient client = new QueryServiceClient();
    DataSet dataSet;
    Paging paging = null;
    CustTransQueryBuilderArgs args = new CustTransQueryBuilderArgs() { parmCustAccount = "4008" };
    dataSet = client.ExecuteDynamicQuery("CustTransQueryBuilder", args, ref paging);


http://msdn.microsoft.com/en-us/library/gg847959.aspx 

Metadata service

Permite obtener información de los metadatos del AOS.
net.tcp://<hostname:port>/DynamicsAX/Services/MetadataService

http://msdn.microsoft.com/EN-US/library/gg880762.aspx


User - session service

Permite obtener información del usuario llamante. (User Company, timezone, …)
net.tcp://<hostname:port>/DynamicsAX/Services/UserSessionService

http://msdn.microsoft.com/EN-US/library/gg881307.aspx



Y nada más; espero que con esta ayuda os hagáis una idea de qué herramientas tenemos disponibles para integrar apps.

Happy interop!!!



miércoles, 5 de septiembre de 2012

Tips integración VS2010 - AX 2012

Aquí os dejo un post con los problemas y soluciones que voy encontrando al tratar de integrar un proyecto .NET en Visual Studio 2010 con Microsoft Dynamics AX 2012



Problema:

Se añade la referencia al Business Connector, pero da el siguiente error:
El tipo o el nombre del espacio de nombres 'Dynamics' no existe en el espacio de nombres 'Microsoft' (¿falta una referencia de ensamblado?)

Solucion:
El proyecto se compila con el Framework Client profile. Hay que poner el Framework 4.0 completo.

Problema:

Al ejecutar el BusinessConnector  (Microsoft.Dynamics.BusinessConnectorNet) da un System.IO.FileLoadException

“El ensamblado de modo mixto se ha compilado con la versión 'v2.0.50727' del runtime y no se puede cargar en el runtime 4.0 sin información de configuración adicional.”
Solucion:

Debemos de añadir en el App.Config (o en el Web.Config, según se trate de WinForms o Webforms) la siguiente entrada:

<configuration>
   <startup useLegacyV2RuntimeActivationPolicy="true">
   </startup>
</configuration>

- Actualización -
Si estás intentando ejecutar una prueba unitaria, hay que modificar el config del siguiente directorio:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.executionengine86.exe.config
Sacado de el blog Diary of a Ninja

Problema:
Da el siguiente error al ejecutar

{"No se puede cargar el archivo o ensamblado 'Microsoft.Dynamics.Ax.Xpp.Support, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ni una de sus dependencias. El sistema no puede encontrar el archivo especificado.":"Microsoft.Dynamics.Ax.Xpp.Support, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"}

Solución: 
Nos falta hacer login en el sesión de ManagedInterop.

     Microsoft.Dynamics.AX.ManagedInterop.Session session = new Microsoft.Dynamics.AX.ManagedInterop.Session();
     session.Logon(null, null, null, null);
     ....
     session.Logoff();



Hasta aquí es todo. Iré actualizando la lista a medida que me encuentre con más cosas.

Saludos.

jueves, 14 de junio de 2012

Error: No se puede cargar el archivo o ensamblado ni una de sus dependencias


Uno de los ordenadores de desarrollo (Windows 7 x64) ha sufrido un cuelgue mientras teníamos un proyecto Web de Visual Studio 2010 abierto, y hemos tenido que darle “botonazo”. (Esto se puede extender a casos como apagones, hibernaciones en portátiles, falta de batería, etc.)

Cuando hemos arrancado el ordenador y hemos abierto de nuevo el proyecto, el Visual Studio nos daba las gracias con un bonito error:

“No se puede cargar el archivo o ensamblado ‘XXX’ ni una de sus dependencias. El parámetro no es correcto.”

Hemos perdido un rato quitando y poniendo referencias, actualizando proxys y ensamblados, sin ningún avance.

La solución era otra:
El Framework .net , cuando compila una aplicación, almacena los ensamblados en sus directorios temporales.

C:\Windows\Microsoft.NET\Framework\[versionNumber]\Temporary ASP.NET Files

Parece que al colgarse el equipo, esas carpetas tenían información incompleta.

La solución ha sido borrar la carpeta correspondiente al proyecto que tiene el problema (dentro de Temporary ASP.NET Files) , y al volverá compilar, se ha regenerado la carpeta temporal de nuevo.

Saludos.

martes, 12 de junio de 2012

Ofuscación de strings, contraseñas y ensamblados .NET

Tenemos un proyecto antiguo entre manos que tiene una contraseña metida en el código.
Sabéis que el código que genera Visual Studio es descifrable fácilmente, por lo que esa contraseña puede ser comprometida fácilmente.
Pongamos las cosas algo difíciles

LA ALTERNATIVA ALGO CHAPUCERA PERO VALIDA

Hay una porción de ese código que necesita ejecutarse con un usuario determinado y diferente al logueado, y para ello usamos una función que internamente usa el “logonUser” de advapi32.dll

Uso la mala técnica de “concatenación de chars” por no guardar la contraseña “a pelo” en los fuentes y ponerlo en bandeja a los fisgones, pero como más adelante veréis, esto no sirve de nada.

Compilamos el proyecto, generando el correspondiente fichero EXE.

Usamos el JetBrains DotPeek, un descompilador free en la línea de .net Reflector

Open… y buscamos nuestro ensamblado.

Navegamos un poco para buscar dónde teníamos la contraseña.


OPS!  La contraseña está perfectamente visible.

Para poder cifrar este ensamblado y poder entregarlo sin excesivo miedo a comprometer la contraseña, usaré un ofuscador. Recordaré que, aunque ofusquemos el código, no está 100% seguro, ya que alguien con conocimientos avanzados y echándole bastantes horas podría llegar a sacar la contraseña.


EAZFuscator, un ofuscador sencillito y free, nos hará la tarea de enmarañar nuesto código para que sea una tarea difícil entender el código fuente desensamblado.


Arrastramos el ensamblado EXE a la zona verde de la ventana, y ya estará ofuscado.


Volvemos a abrir con el DotPeek, y vemos que el código nos lo ha dejado hecho unos zorros… pero de eso se trataba!!!





 Lo dicho; seguro que echándole muchas horas y mucha paciencia podríamos llegar a sacar alguna cosa de un código ofuscado, pero por lo menos se lo hemos puesto algo difícil.

LA ALTERNATIVA RECOMENDADA

Microsoft recomienda, para estos casos, poner la contraseña en un archivo de configuración y cifrar la sección.




En el caso que se quiera distribuir un único EXE sin tener que adjuntar ficheros de configuración, siempre podremos incrustar el fichero de configuración dentro del ensamblado.


Saludos.

lunes, 21 de mayo de 2012

Multiidioma. Sincronizar varios archivos de recursos

Cuando trabajando con aplicaciones multiidioma, lo normal y lo recomendable es hacerlo mediante archivos de recursos localizados (*.resx, *.en-resx, *.es-mx.res)

http://msdn.microsoft.com/es-es/library/ms227427.aspx

Esto requiere de un poco de tacto, ya que debemos tener las mismas claves en los diferentes archivos de recursos.

Añadir, modificar o borrar un recurso cuando gestionas más de 3 recursos puede ser un poco tedioso.

Pensaba crearme una herramienta para poder gestionar varios recursos sincronizados a la vez,  pero me dio por buscar y encontré una herramienta que ya hacía esto. (afortunadamente o desgraciadamente, ya está todo inventado)

Se trata de Zeta Resource Editor.

http://www.codeproject.com/Articles/16068/Zeta-Resource-Editor

Tiene incluso opción de traducción automática por Bing o Google Translator.

Espero que os sea útil!!!

Saludos.






jueves, 17 de mayo de 2012

Generación de clases POCO


Estoy haciendo un curso de desarrollo de Asp.net  y así me desintoxico de tanto winforms impartido por CampusMVP (altamente recomendable!!!) y me ha surgido una duda.

Estaba viendo los DataAnnotations para un ejemplo en MVC y me planteaba el poder generar las clases “buddy” automáticamente del Entity Framework en vez de crearlas de nuevo para aplicarles las annotations.  Pensaba en esas tablas de más de 30 campos que suelen haber en escenarios reales.

No me acordaba que el Entity Framework es un generador automático de código.

Con Entity Framework y la plantilla adecuada se pueden generar clases POCO, (Plain Old CLR Objects) o, traducido, Objetos simples y planos.

Entity Framework es un generador de código


El Entity Framework, cuando se compila, genera un “code-behind” del archivo EMDX (con extensión Desiger.cs) que contiene un código autogenerado a partir del modelo de entidades, que son en realidad los objetos que manejamos cuando trabajamos con él.

Si buceamos un poco dentro de ese archivo, encontraremos las regiones “Contextos” y “Entidades”.

Dentro de cada entidad,  “Métodos de generador”, “Propiedades primitivas” y "Propiedades de navegación".

Dentro de "Propiedades primitivas" tenemos las propiedades de la clase, aunque algo enmarañadas con el código que genera el Entity Framework, y que tanto papel nos hace (guardado, recuperación, intellisense, tipado, etc...)


Cambiando el generador de código por defecto.


Como hemos visto, el Entity Framework genera código. Podemos cambiar el generador de código por defecto por uno que funcione como queremos, o incluso, crear nosotros mismos las plantillas de generación de código. (Plantillas T4)



De hecho, el Entity Framework usa plantillas T4 para generar el modelo de entidades.


En la ventana de propiedades del Entity Framework, le estamos indicando que genere el código usando la plantilla T4 "SSDLToSQL10.tt"

Podemos cambiar el generador de código pulsando botón derecho en algún hueco del explorador de entidades del EF, y eligiendo "Agregar elemento de generación de código".



Nos aparecerán los generadores de código que tenemos instalados (El generador por defecto de Entity Framework y el generador de STE(Self-Tracking entities)).



Si pulsamos sobre Plantillas en línea, se muestran las plantillas disponibles a descargar.

Sobre el menú Base de datos, elegiremos EF 4.0 DBContext Generator for C# (me imagino que también habrá para VB.NET)


Al instalar esta plantilla se guardan en nuestro proyecto 2 plantillas t4 vinculadas al modelo de Entity Framework. Una contiene el contexto y otra las entidades.



TACHAAAAN. Ya tenemos generadas las entidades POCO




Detalle del contexto.

        public DbSet<Category> Categories { get; set; }
        public DbSet<CustomerDemographic> CustomerDemographics { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Order_Detail> Order_Details { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<Product> Products { get; set; }
        public DbSet<Region> Regions { get; set; }
        public DbSet<Shipper> Shippers { get; set; }
        public DbSet<Supplier> Suppliers { get; set; }
        public DbSet<Territory> Territories { get; set; }

Detalle de una entidad

    public partial class Employee
    {
        public Employee()
        {
            this.Employees1 = new HashSet<Employee>();
            this.Orders = new HashSet<Order>();
            this.Territories = new HashSet<Territory>();
        }
   
        public int EmployeeID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string Title { get; set; }
        public string TitleOfCourtesy { get; set; }
        public Nullable<System.DateTime> BirthDate { get; set; }
        public Nullable<System.DateTime> HireDate { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string HomePhone { get; set; }
        public string Extension { get; set; }
        public byte[] Photo { get; set; }
        public string Notes { get; set; }
        public Nullable<int> ReportsTo { get; set; }
        public string PhotoPath { get; set; }
   
         public virtual ICollection<Employee> Employees1 { get; set; }
        public virtual Employee Employee1 { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
        public virtual ICollection<Territory> Territories { get; set; }
    }



Para que nos compile esta plantilla sería necesario tener Framework 4.1 (usa System.Data.Entity.Infrastructure),  y encima tenemos deshabilitado el generador predeterminado de Entity Framework para que no se generen entidades duplicadas, pero para lo que queremos, que es obtener las clases POCO de nuestras entidades, no es necesario.

 Así que copiamos las clases generadas en una carpeta, y deshagamos el camino.


Volvamos al generador de código por defecto.

 

¿Qué ha pasado con el Entity Framework?

Las nuevas plantillas están usando las entidades del EF, pero éste está deshabilitado.


Fijémonos en las clases generadas por el Entity:

// La generación de código predeterminada está deshabilitada para el modelo 'C:\*******\MvcApplication1\MvcApplication1\Models\Model1.edmx'.

// Para habilitar la generación de código predeterminada, cambie el valor de la propiedad del diseñador 'Estrategia de generación de código'

// por otro valor. Esta propiedad está disponible en la ventana Propiedades cuando se abre

// el modelo en el diseñador.



Para deshacer el camino, borramos las dos plantillas T4 que ha creado la plantilla (los ficheros *.tt) y cambiemos la propiedad del Entity Framework "Estrategia de generación de código" a "Predeterminados"
 

Con esto hemos conseguido generar unas clases POCO que nos pueden servir para muchas cosas, como para las validaciones con MVC y DataAnnotations, clases para pasarlas entre capas, etc.

Saludos!!!