EF 6: Ejemplos de operaciones de migracion

Tal y como hicimos en la entrega anterior vamos a ir poniendo ejemplos completos de algunos de los puntos de extensibilidad que tenemos en Entity Framework 6. En esta ocasión hablaremos de operaciones de migración, algo que ya comentamos en alguna entrada anterior, como esta. Tal y como explicamos en su momento, esto nos permite cubrir de forma personalizada con operaciones que no tengamos out of box.

Como en la entrada anterior, el código se puede descargar desde:

https://github.com/unaizorrilla/ef.contrib

 

Creación y borrado de vistas

 

A pesar de que esto suele ser habitual, estas opciones no las tenemos por defecto como operaciones de migración, por lo que son unos buenos candidatos de ejemplo. A continuación podemos ver el código de la operación CreateViewOperation.

 

La operación de borrado es también bastante sencilla:

 

Bien, ahora que ya tenemos creadas las operaciones solamente queda registrarlas en nuestro generador, que crearemos para darle soporte, tal y como se ve:

 

Si observa, hay un pequeño truco para no hacer “feas” conversiones de nuestras operaciones y ejecutar código en función de la que sea, y consiste en utilizar el tipo dynamic, gracias al cual podremos redirigir al generador de la operación que necesitemos…

 

Para finalizar, ahora que tenemos nuestras operaciones y nuestro nuevo generador, solamente nos queda registrarlo…

Como se imaginará hay muchas más operaciones que podríamos construir para nuestras migraciones, cosas como el manejo de permisos, collation son algunas de las otras operaciones que tiene en el código de ejemplo que se hace referencia al principio del post.

 

Saludos

unai

EF 6: Un ejemplo de pluralizador en castellano

Desde hace ya un tiempo vengo recibiendo bastantes correos con respecto a una de las nuevas características de EF 6 referida al sistema de pluralización. Aunque ya en este mismo blog he hablado un poco sobre esta característica la verdad es que no había enseñado un ejemplo completo. Por eso, intentaré  publicar en este blog ejemplos completos sobre algunas piezas de las que hemos hablado en EF 6 pero de las que no hemos dado ejemplo completos, para este y para los siguientes posts, el código lo puede descargar desde GitHub:

 

https://github.com/unaizorrilla/ef.contrib.git

 

Para la creación del sistema de pluralización en castellano intenté no reinventar la rueda y ver como otros hacían este trabajo, como por ejemplo Andrew Peters. @anpete –  developer de  ADO.NET EF, con su Inflector .NET. Para las reglas de pluralización en castellano uno puede ver los diferentes documentos que hay en internet sobre esto, basta abrir Bing y hacer una pequeña búsqueda para ver cantidad de enlaces. Después de leer sobre estas reglas un posible esbozo del pluralizador podría ser el siguiente, por supuesto el código tiene sus correspondientes tests que si os interesa podríais ayudar a mejorar incluyendo nuevos casos de prueba, tanto para los elementos irregulares como para los regulares.

 

 

Bien, ahora que ya tenemos el pluralizador creado, para establecerlo lo tenemos tan fácil como usar nuestro DbConfiguration.

 

EF 6: Multiples contextos y migraciones para la misma base de datos

Una de las nuevas características de EF 6 es el soporte para múltiples modelos en una base de datos, creo que alguna vez lo he mencionado desde este mismo blog. Tal y como podemos ver en el feature specification  del equipo de producto esta característica se basa principalmente en la nueva propiedad ContextKey de nuestra tabla MigrationHistory y la propagación del esquema de cada contexto. Aunque ya hay algunos ejemplos de esta característica por internet como por ejemplo este de Julie, me gustaría ver un pequeños trick para aprovecharnos de esta característica con diferentes contextos en un mismo proyecto.

Como todos sabéis, el primer paso para habilitar las migraciones es ejecutar el comando enable-migrations, el cual por defecto, nos crea una nueva carpeta llamada Migrations con la configuración de la migración de un contexto de trabajo. El problema es que, si tenemos varios contextos, este comando no sabrá de cual queremos hacer nuestra configuración de migración y nos mostrará un mensaje como el siguiente:

 

PM> enable-migrations
More than one context type was found in the assembly ‘MultipleContextDatabase’.
To enable migrations for ‘MultipleContextDatabase.ContextA.ContextA’, use Enable-Migrations -ContextTypeName MultipleContextDatabase.ContextA.ContextA.
To enable migrations for ‘MultipleContextDatabase.ContextB.ContextB’, use Enable-Migrations -ContextTypeName MultipleContextDatabase.ContextB.ContextB.

Aunque en principio, estemos tentados por probar alguna de las soluciones que el mensaje de error nos ofrece, en realidad no ganaremos nada, puesto que lo único que haríamos es tener habilitadas las migraciones para alguno de los contextos pero no para ámbos como necsitamos. La solución, para tener varias configuraciones de migración, es que las mismas estén en diferentes carpetas, para lo cual podemos aprovecharnos del flag MigrationsDirectory.

PM>enable-migrations -ContextTypeName MultipleContextDatabase.ContextA.ContextA -MigrationsDirectory:MigrationsA

 

PM>enable-migrations -ContextTypeName MultipleContextDatabase.ContextB.ContextB -MigrationsDirectory:MigrationsB

 

 

Con estas dos sencilla ejecuciones ya tenemos nuestras dos configuraciones de migración creadas. Por supuesto, para crear nuevas migraciones o actualizar la base de datos será necesario especificar que configuración de migración queremos usar, por ello, todos los comandos ponen a nuestra disposición el flag ConfigurationTypeName. A continuación, podemos ver un ejemplo:

 

PM> Add-Migration Initial -ConfigurationTypeName MultipleContextDatabase.MigrationsA.Configuration

 

 

Bien, hasta aquí este pequeño trick

 

Un saludo

Unai

EF 6: WebCast ADO.NET Entity Framework

El próximo día 30 de Mayo, tendremos el placer de poder realizar un WebCast con Diego Vega, Developer Lead de Entity Framework, hablando de todo lo que rodea a EF 6, desde el nuevo modelo de desarrollo OSS hasta las principales características de esta nueva versión. Sinceramente, creo que es una gran oportunidad tener con nosotros a Diego y poder ver de su mano que tendremos próximamente en EF, así como tener la posiblidad de hacerle todas las preguntas que consideréis oportunas…

 

Aquí os dejo el enlace de registro, espero veros a todos por allí

 

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032553975&Culture=es-ES&community=0

 

Saludos

Unai

EF 6: Operaciones de migraciones personalizadas

Hace ya un tiempo, el buen amigo @iceoverflow ,hizo un pequeño pero muy interesante pull request que nos habilita la posibilidad de crear y enchufar nuevas operaciones de migración que no tengamos por defecto en Entity Framework. Aunque el proceso es un poco mecánico, abre un montón de posibilidades para hacer nuevas contribuciones, incluso aunque no sea directamente en el código de EF y si en alguna contribución ( tengo una pequeña sorpresa con esto pero ya os la contaré cuando esté más avanzada ). A continuación me gustaría enseñaros un pequeño ejemplo de lo que podemos hacer y, por supuesto, todo aquello que os gustaría tener me encantaría escucharlo e incluso hacerlo…

Bien, empezamos, trataremos de hacer una operación de migración para crear una vista, lo primero por lo tanto es definir la operación, para ello, solamente tenemos que heredar de MigrationOperation, como por ejemplo vemos a continuación:

 

Bien, ahora que ya tenemos definida nuestra operación, ya la podemos incluir dentro de nuestras migraciones, para que quede de una forma consistente con las operaciones actuales, podríamos crear un método extensor de de DbMigration como el siguiente:

 

 

Una vez hecho este trabajo, cuando una operación se ejecute, esta operación se enviará al generador sql que tengamos configurado,recuerde que puede establecerlo ahora con nuestro punto central de configuración DbConfiguration. Por lo tanto, este generador debe de estar preparado para procesar estas operaciones, por lo tanto, lo normal será partir de un generador dado como por ejemplo SqlServerMigrationSqlGenerator para extenderlo con esta nueva operación. Para nuestro ejemplo podríamos hacer algo como lo siguiente:

 

Ahora, en nuestro Generate deberíamos ver como procesar cada una de las posibles operaciones personalizadas que podamos querer incluir, para facilitar la tarea y no ver demasiada conversión o switch un truquito rápido sería este:

 

Al ponerlo como dynamic podemos crear un método para cada una de las operaciones personalizadas y por lo tanto simplificar tanto la lectura como el mantenimiento del código.

 

Espero que os haya gustado esta posibilidad, por supuesto, para los que os habéis fijado en el código esto forma parte de un proyecto que ya contiene muchas más posibles operaciones de migración que pronto compartiré con todos vosotros, de ahí que os preguntará que os gustaría tener!!, animaros…

 

Saludos

unai

Commands y Windows Azure ServiceBus

Bueno, un post pequeñito pequeñito, más que nada y para ser sincero, para cambiar un poco de tercio, pero que espero que os resulte interesante. Hace ya bastante tiempo, los pocos que leéis mi aburrido blog, escribí acerca de eventos de dominio y agregados. En esta ocasión me gustaría hablar de comandos y de alguna pequeña ayuda que el nuevo SDK de Azure nos trae para implementaciones de nuestros manejadores. Si bien, comandos y eventos, en realidad son cuestiones semánticas y poco más, uno en pasado, otro acción, receptores y poco más  la verdad es que su implementación se parece muchísimo, puesto que en ambos tenemos un consumidor ( o N en realidad )  capaz de despachar acciones, la información del evento producido o el comando ejecutado. La implementación de estos despachadores ( que feo.. ) suele ser más o menos sencilla cuando estamos modelando nuestro sistema pero en realidad, a la hora de ir a un sistema real el tema se complica y muchas veces se acaba por utilizar algunas buenas piezas ya construidas como puede ser NServiceBus de Udi Dahan.

 

Nota: Para los que os interese NServiceBus y todo lo relacionado con este bloque de código os recomiendo el blog de MarÇel Serrate.

 

Pues bien, la nueva versión del SDK de Azure, SDK 2.0, incluye una pequeñita mejora en el procesado de mensajes de una cola, habitual para la implementación de un dispatcher de comandos y eventos, de tal forma que el patrón de recepción y vuelta a escuchar de los mensajes en nuestra cola se simplifique muchísimo introduciendo un patrón de eventos. Concrétamente veremos que el API cliente para manejar nuestras colas dispone de un nuevo método OnMessage con el que podremos especificar  donde haremos el procesado de los mensajes y el establecimiento de diferentes opciones como el auto completado de los mensajes, el número máximo  de llamadas concurrentes y/o el método a utilizar para manejar excepciones que se produzcan en la recepción de los mensajes. Un ejemplo trivial de esto podría ser:

 

 

Ahora, solamente necesitaríamos nuestro método de manejo, OnMessageArrived, dónde pondríamos la lógica de tratamiento de estos comandos/eventos para asignárselos a sus correspondientes manejadores.

 

 

Sencillo, ¿verdad?… Bueno, ya os dije que sería una entrada cortita…

 

Unai

EF 6: Command rewriters – I

En las dos últimas dos entradas he hablado sobre el nuevo bloque introducido en Entity Framework 6 para la realización de intercepciones. Aunque en principio solamente hemos hablado de lo básico, como por ejemplo los diferentes tracers, más aún con la nueva propiedad Database.Log, en realidad este bloque nos permite hacer cosas mucho más interesantes como por ejemplo el re-write de consultas. Si nos fijamos un poco en nuestra nueva clase DbInterceptor esta nos expone dos interfaces fundamentales IDbCommandInterceptor y IDbCommandTreeInterceptor de las que realmente podremos partir si queremos algo mucho más “a bajo nivel” dentro de la infraestructura de Entity Framework.  Con el fin de ver algo diferente a los procesos de instrumentalización de las consultas vamos a intentar crear algún ejemplo de intercepción con reescritura de consulta utilizando estas dos interfaces.

 

IDbCommandInterceptor, reescritura de tu SQL

Como ya hemos comentado, esta interfaz nos ofrece los procesos de pre y post para las tareas habituales con la base de datos como por ejemplo son la ejecución de consultas y comandos. La idea para nuestra reescritura es poder introducir algún mecanismo que nos permita identificar un comando y proceder a su cambio, para verlo construiremos la siguiente clase CommandRewriter, la cual esta hecha a modo de ejemplo, intentaré poner pronto a vuestra disposición una implementación más apropiada de un sistema de reescritura de consultas.

 

Si nos fijamos, en realidad, no hemos hecho absolutamente nada, simplemente hemos puesto una pequeña comprobación antes de la ejecución de los comandos que nos permita identificar si ese comando es candidato a ser reescrito. En caso afirmativo procedemos a la tarea. Un ejemplo evidente de esta reescritura se produce cuando queremos cambiar una consulta exacta por otra, por ejemplo para poder utilizar algún hint, cambiar un parámetro etc. para esto, podríamos hacer algo trivial como sigue:

 

 

Ahora, que hemos creado estas simples bases, podríamos introducir una reescritura por ejemplo como la siguiente, que es solamente con fin ilustrativo, , en la que introducimos un hint NOLOCK en la consulta:

 

Una vez creado nuestro rewriter solamente nos queda asignarlo, para lo cual, como ya sabemos de otras entradas tenemos nuestra clase Interception.

 

A lo largo de esta entrada hemos podido  ver como los interceptores sirven para mucho mas que para las trazas de nuestras consultas y podemos tener una ganancia importante con su uso dentro de nuestras aplicaciones. En esta primera edición hemos visto la intercepción de nuestras consultas SQL, para la siguiente intentaremos ver como modificar nuestros arboles de consulta antes de generar el SQL.

Saludos

Unai

EF 6: Interceptors, segunda iteración

Es lo malo de escribir posts con todo en desarrollo, que se quedan desactualizados de un día para otro, de hecho, no tengo mucha idea de cuanto os pueden aportar, a vosotros amigos lectores, estas entradas que hago sobre EF 6 y quizás seguramente  estoy perdiendo el tiempo, pero me cuesta, aún así, resistirme a hacerlo.

En la anterior entrada hemos visto los primeros pasos con interception y como podíamos configurar esta, después del último commit de Arthur algunas cosas han cambiado y en mi opinión creo que han quedado mejor, mas consistentes con el diseño actual.

 

El primer cambio es la creación de un DbCommandLogger y un DbCommandLoggerFactory, que nos permitirán disponer de una clase para el log de los diferentes comandos con una implementación por defecto que hace la escritura en un TextWriter que podemos establecer en su constructor.

 

Para establecer este DbCommandLogger tenemos una nueva propiedad en nuestro objeto Database que nos permite establecer un TextWriter a utilizar, en realidad aunque lo que hacemos en esta propiedad es establecer el TextWriter internamente se establecer un command logger con ese text writer. Fíjese en nuestro siguiente código como podemos establecer la consola de salida como logger de los diferentes comandos ejecutados por Entity Framework.

 

 

Por supuesto, si queremos cambiar nuestro DbCommandLogger por defecto podremos hacerlo, para ello, como siempre podemos acudir a nuestro DbConfiguration y establecer un Dependency Resolver o bien setearlo con el nuevo método SetCommandLogger.

 

 

Bueno, lo dicho, no se si estas pinceladas son interesantes para vosotros amigos lectores, pero espero que si y sobre todo que dejéis feedback de lo que necesitáis en el producto.

 

Saludos

Unai

EF 6: Sorpresa, interceptors

Pues si, digo bien con sorpresa, porque hasta ahora yo no era consciente de que esta fuera a ser una de las nuevas características de EF 6, de hecho si miramos el roadmap veremos que no estaba contemplada. Pero por lo que sea ya tenemos aquí los primeros commits relacionados con la posibilidad de implementar mecanismos de intercepción en la nueva versión de Entity Framework. Aunque seguramente cambiarán ciertas cosas hasta la versión final,  no me puedo resistir a enseñaros alguna pincelada.

 

Interception

 

La clase estática Interception representa por ahora el punto dónde podemos agregar y quitar nuestros interceptores. En realidad, esto me ha chocado un poco porque creía que era un patrón obsoleto como el uso de Database en anteriores versiones, y creo que va a cambiar,  aunque en el tablero de preguntas del proyecto hay una pregunta abierta que espero que respondan. Esta clase es tan simple como vemos a continuación.

 

Como se puede ver, en realidad, lo que nos ofrece es un mecanismo para agregar y quitar interceptores, pensado en enchufar los mismos solamente en ciertas partes del trabajo o momentos determinados. De hecho la nueva característica de scaffolding de los procedimientos almacenados se basa en esta infraestructura. A mayores de esto, vemos como un interceptor no es más que cualquier clase que implemente IDbInterceptor, por suerte, a nosotros ya nos ofrecen una clase base  de la que partir llamada DbInterceptor, que será la que usemos por norma general.

 

 

Como podéis ver, hay muchos métodos en los que nos podemos enganchar, tanto para llamadas síncronas como asíncronas, así como a ciertores pre-post procesos, como por ejemplo en la ejecución de comandos. Un hola mundo, podría ser el siguiente, donde sacamos por la consola las consultas de lectura ejecutadas por EF:

 

Feedback

 

Estoy seguro que todo el equipo va a necesitar feedback de esta nueva característica, que os gusta, que no, que necesitáis que no tengáis etc. por eso me gustaría pediros a todos que os animéis a pasar por el portal del producto y dejar vuestras necesidades / recomendaciones etc…

 

Saludos

Unai