Explicación de Microsoft POCO y plantillas de seguimiento automático

Si un desarrollador necesita realizar ciertos cambios o ajustar el comportamiento de las plantillas POCO o las plantillas de seguimiento automático de EntityFramework, o escribir una plantilla personalizada desde cero basada en una plantilla estándar de Microsoft, deberá aprender cómo funcionan esas plantillas.

Al estudiar las plantillas de generación POCO y Self-Tracking de Microsoft, encontré dificultades significativas para comprender la forma exacta en que funcionan estas plantillas, ya que están lejos de ser triviales. En este artículo de blog, intentaré describir sus características principales, explicar algunos puntos que pueden ser tan fáciles de entender y la estructura de las plantillas. Con suerte, esta información será útil y ahorrará tiempo y esfuerzo para todos los desarrolladores que necesitan trabajar con plantillas de generación de Microsoft para modelos de EntityFramework.

Las plantillas estándar de Microsoft están escritas en el lenguaje de plantillas T4. Puede encontrar sus descripciones, procedimientos de adición y una pequeña configuración de muestra aquí: http://msdn.microsoft.com/en-us/gg558520. Este artículo proporciona información básica sobre las plantillas de generación T4 para EntityFramework que se requieren para usarlas, así como información detallada sobre cómo trabajar con metadatos, generar múltiples archivos y algunos otros aspectos.

Ahora veamos cómo se diseñan POCO y Self-Tracking de Microsoft y cómo se pueden usar en el desarrollo de aplicaciones.

Índice

Archivos de plantilla

Ambas plantillas constan de dos archivos: <імя мадэлі>.Contexto.tt y <назва мадэлі>.tt. Archivo de plantilla <імя мадэлі>.Context.tt también genera el código ObjectContext del modelo EntityFramework <імя мадэлі>.tt genera clases para Entidades y tipos de modelos complejos, así como clases adicionales requeridas por el modelo generado para funcionar correctamente. Este archivo de plantilla POCO también genera un archivo <імя мадэлі>.cs que contiene el archivo FixupCollection clase necesaria para generar informes en modelos POCO.

La plantilla de seguimiento automático también genera archivos adicionales que contienen las clases y las interfaces que necesita el modelo para funcionar correctamente (para obtener más información, consulte http://msdn.microsoft.com/en-us/library/ff477604.aspx).

Clases, funciones y estructuras que se utilizan con más frecuencia en las plantillas

El WriteHeader la función se utiliza para crear el encabezado del archivo de salida de cada plantilla; es responsable de generar el mismo tipo de código al comienzo de cada archivo: comentarios que describen el archivo y declaraciones del conjunto de espacios de nombres utilizados.

El Clase CodeRegion se utiliza en plantillas para insertar regiones en el código generado y para controlar las sangrías en el código. Su Línea de salida) y Fin () Los métodos se utilizan para asignar #region y #endregion al código C # generado y para omitir la región si la plantilla no genera código dentro de la región. El nombre de la región se envía a Línea de salida) funciona como un parámetro, y la propia clase calcula las sangrías para la región actual.

También puedes usar plantillas CodeRegion.GetIndent (int)un método estático de esta clase para obtener una cadena de espacios equivalente al número de sangrías necesarias.

El resultado está de vuelta CodeRegion.GetIndent (int) la función se envía a PushIndent (cadena) función de plantilla. Esta función de plantilla es responsable de establecer sangrías para generar código porque obtiene un valor de sangría que se agregará como prefijo a cada línea generada por la plantilla de código. De esta manera, podemos controlar el formato del código generado. El PopIndent () el método de plantilla restablece el valor de sangría actual y devuelve el valor anterior que se utilizará para fines de formato.

Clase EntityFrameworkTemplateFileManagerEntityFrameworkTemplateFileManager class utilizado en la plantilla para gestionar los archivos de salida. Su funcionalidad está bien descrita en el artículo de MSDN (ver enlace al principio de este artículo), por lo que no me extenderé más en este tema.

Class CodeGenerationTools

Esta clase se usa más comúnmente en plantillas. Al principio de la plantilla puedes ver cómo se crea la variable local "código"; esta variable se usa a menudo en la plantilla. Escaparsu función más utilizada, tiene muchas sobrecargas y se usa para convertir una representación de cadena de un objeto de forma segura para el compilador.

Por ejemplo, su modelo tiene un objeto llamado "clase"; este nombre es el nombre de clase para este objeto, y se genera el siguiente código para él:

public class <entity name>

Sin embargo, no es posible usar el identificador de "clase" para el compilador de C#, porque el compilador no procesará el siguiente código:

public class class …

Para usar la palabra reservada "clase" como nombre de clase, necesitamos convertirla a la forma legal del compilador:

public class @class …

El Escapar la función verifica si es necesario convertir la identificación a una forma segura y, de ser así, realiza la conversión y devuelve la identificación siempre válida. El Espacio de nombres de escape la función usa el mismo flujo de trabajo y siempre devuelve un identificador que se puede usar legalmente como un nombre de espacio de nombres.

La segunda característica más utilizada de esta clase, Nombre del campodevuelve el nombre del campo interno del miembro de la clase, y este nombre se forma como el nombre del miembro de la clase con el prefijo "_".

El Versión abstracta la función comprueba si la clase definida en los metadatos del modelo es abstracta y, de ser así, devuelve el ID de compilador legal de la clase abstracta.

El CreateLiteral (valor de objeto) la función convierte el objeto en una cadena de código para su inicialización del compilador. Por ejemplo, si se envía un valor de tipo System.Guid a una función, obtenemos la siguiente línea: “nuevo Guid (“<радкавое прадстаўленне адпраўленага аб’екта>”)”. Esta función se utiliza para generar código que inicializa los valores predeterminados de las propiedades del objeto cuando los valores predeterminados están definidos en los metadatos.

No describiré otras funciones de clase, ya que rara vez se usan y son intuitivas.

Clase de disponibilidad

Esta clase también se usa con bastante frecuencia en plantillas y es un conjunto de funciones estáticas que devuelve una representación de la ID de acceso de objeto legal del compilador.

Otras estructuras

Cuando se trabaja con instalaciones de navegación, a menudo puede encontrarse con el diseño (Tipo de asociación)<імя ўласцівасці навігацыі>.RelationshipType) .IsForeignKey. Esta estructura vuelve Cierto si la asociación tiene una restricción de referencia. El <імя ўласцівасці навігацыі>.ToEndMember.GetEntityType () devuelve el objeto al que hace referencia la propiedad de navegación. Método ObtenerPropiedadesDependientes () obtiene una colección de propiedades que están en el extremo dependiente de la restricción de referencia para una propiedad de navegación determinada. El ObtenerPropiedadesPrincipal el método de propiedad de navegación obtiene una colección de propiedades que se encuentran en el extremo principal de la restricción de referencia para una propiedad de navegación determinada.

Características de la plantilla <назва мадэлі>.Contexto.tt

<імя мадэлі>.Context.tt no contiene ninguna dificultad o aspecto que no se haya descrito anteriormente y genera un código de clase de contexto bastante trivial que incluye propiedades de ObjectSet y funciones de importación.

Para crear un seguimiento automático, esta plantilla también contiene código para crear un archivo adicional <імя мадэлі>.Contexto.Extensiones.cs:

fileManager.StartNewFile
    (Path.GetFileNameWithoutExtension(Host.TemplateFile) + ".Extensions.cs");
    BeginNamespace(namespaceName, code);
    WriteApplyChanges(code);  // generates the main content of the file
    EndNamespace(namespaceName);

Características de la plantilla <назва мадэлі>.tt

<Назва мадэлі>.tt es mucho más difícil. Desde el principio, se debe decir que la gran cantidad de código en la plantilla de Self Tracking no debe intimidar: este código no es tan complicado como puede parecer a primera vista.

Código para generar <імя мадэлі>.cs se encuentra al principio de la plantilla.
En la plantilla para POCO se ve así:

WriteHeader(fileManager);
BeginNamespace(namespaceName, code);
WriteCustomObservableCollection();// generates the main content of the file
EndNamespace(namespaceName);

El archivo generado contiene el archivo FixupCollection una clase que se requiere para generar informes en modelos POCO.

En la plantilla de seguimiento automático, se ve así:

WriteHeader(fileManager);
BeginNamespace(namespaceName, code);
WriteObjectChangeTracker();
WriteIObjectWithChangeTracker();
WriteCustomObservableCollection();
WriteINotifyComplexPropertyChanging();
WriteEqualityComparer();
EndNamespace(namespaceName);

El archivo generado contiene todas las clases e interfaces que se requieren para que el modelo funcione correctamente. Para obtener más información sobre el tema, consulte http://msdn.microsoft.com/en-us/library/ff477604.aspx.

Generación de esencia

El patrón se repite sobre los objetos del modelo, lo que da como resultado la creación de clases para cada entidad. La posible herencia se tiene en cuenta al generar una definición de clase. La generación de clases se divide en las siguientes regiones: generación de propiedades primitivas, generación de propiedades complejas (cuyo tipo es complejo), generación de propiedades de navegación y generación de arreglos de asociación. El área ChangeTracking también se genera para la plantilla de autoseguimiento.

Una región de propiedades primitivas

El reino de las propiedades primitivas contiene las propiedades generadas de la esencia del tipo simple (no complejo). Si la propiedad se establece en el valor predeterminado, este valor se utiliza para generar el código de inicialización que se ejecuta Crear letras propiedad c CodeGenerationHerramientas clase. Si la propiedad es una propiedad de clave externa, es decir, si hay una propiedad de navegación que hace referencia a una clase maestra para el objeto, y la propiedad primitiva creada participa en la restricción referencial de esta asociación de propiedades de navegación, el depurador genera una método de código adicional para guardar las asociaciones de propiedad de reparación.

En la plantilla de autoseguimiento IsOriginalValueMember (EdmProperty edmProperty) metodo c Miembros del valor original la clase regresa Cierto si la propiedad ConcurrencyMode de la propiedad generada tiene un valor fijo o si la propiedad generada es una propiedad de clave externa.

Propiedades del complejo Reg

El dominio Propiedades complejas contiene las propiedades generadas de la entidad de tipo complejo.
La plantilla POCO para un campo de clase genera un código de inicialización con un nuevo valor de este tipo complejo.
La plantilla Self-Tracking no realiza esta operación, ya que en los códigos que genera se realiza la inicialización de un campo de tipo complejo especificando la propiedad adecuada.

Propiedades de navegación de la región

La región Propiedades de navegación contiene las propiedades de navegación del objeto creado. Según la propiedad de navegación Multiplicity, se genera una propiedad que contiene una instancia de la clase maestra para la entidad o una colección de clases de detalle.

Características de los métodos de la clase MetadataTools para plantillas de seguimiento automático

Al crear una propiedad de navegación con Multiplicidad = Muchos, el IsCascadeDeletePrincipal (NavigationProperty navProperty) metodo c Herramientas de metadatos la clase regresa Ciertosi la acción de la propiedad de navegación OnDelete tiene un valor en cascada o la colección de propiedades que se encuentran en el extremo principal de la restricción de referencia para una propiedad de navegación determinada contiene al menos una propiedad de clave de entidad.

Al crear una propiedad de navegación con Multiplicidad = Muchos, el IsPrincipalEndOfIdentifyingRelationship (AssociationEndMember AssociationEnd) metodo c Herramientas de metadatos la clase regresa Ciertosi la colección de propiedades que están en el extremo dependiente de la restricción de referencia para una propiedad de navegación dada contiene al menos una propiedad de clave de propiedad.

Seguimiento de cambios de región en la plantilla de seguimiento automático

La región ChangeTracking, que solo está disponible en la plantilla de autoseguimiento, contiene Seguimiento de cambios propiedad y métodos que están con la lógica de sincronización de relaciones.

En esta región se debe prestar atención a IsSaveReference (herramientas MetadataTools, NavigationProperty navProperty) el método de la plantilla en sí. Este método devuelve Ciertosi es una asociación de clave externa que se agrega sin agregar propiedades de clave externa, es decir, la restricción de referencia no se usa en su mapeo.

Asociación de Enmienda de la Región

La región de corrección de asociación contiene técnicas generadas que se utilizan para actualizar asociaciones y propiedades de navegación al realizar cambios. Además de las características descritas anteriormente, todos los demás aspectos de esta región son pocos e intuitivos.

Generación de tipos complejos

Después de generar objetos, la iteración pasa a tipos de modelos complejos para los que se generan clases. Esto incluye la creación de definiciones de clase, así como propiedades primitivas y complejas. ChangeTracking también se genera para la plantilla de autoseguimiento.

Con suerte, este artículo lo ayudará a dominar las plantillas estándar de POCO y Self-Tracking de Microsoft para crear modelos de EntityFramework.

Artículos de interés

Subir