19

El patrón de repositorio se utiliza para abstraer de una base de datos particular y la tecnología de mapeo de relaciones de objetos (como EF) utilizada. Así que puedo reemplazar fácilmente (por ejemplo) mis asignaciones de marcos de entidades con Linq a SQL en el futuro si así lo decido.Patrón de repositorio con Entity framework

Pero cuando uso EF tengo mis clases de entidades del modelo, es decir, se generan a partir de ese diagrama visual. Si uso estas clases de entidad generadas en mi repositorio y luego decido reemplazar EF por otra cosa, entonces eliminaré ese diagrama de entidad visual y eso significa también eliminar clases ¿verdad?

El punto al que me refiero es que mi repositorio dependerá del marco de la entidad, es decir, de la capa de acceso a los datos porque usará las clases generadas por EF.

¿Cómo elimino esta dependencia?

También tenga en cuenta que utilizo EF principalmente por su capacidad de generar todo a partir de ese diagrama visual - Solo diseño el diagrama y dejo que genere una base de datos con todas las claves externas etc. Me gusta mucho y no lo hago quiero siquiera pensar en los comandos SQL.

Respuesta

27

Un repositorio siempre depende de la tecnología de acceso a datos. Esta es la razón por la cual las personas están usando repositorios para envolver la dependencia de acceso a datos en una capa separada. Si decides cambiar la tecnología de acceso a los datos (aunque es un 1% de probabilidad de que lo hagas), deberás crear repositorios nuevos que implementen las mismas interfaces que los anteriores.

Introducir repositorios agregará una nueva capa de complejidad. Los repositorios tienen sus pros y sus contras. Presentarlos simplemente porque "puede cambiar el enfoque de acceso a datos en el futuro" es una mala razón. No diseñe su aplicación porque algo puede suceder. Diseñe la aplicación según los requisitos reales actuales (de una manera ágil) y refactorice su código si se necesita un cambio: esa es la única forma de ser competitivo en el mercado. Las características son vender su SW no su arquitectura abierta para cualquier tipo de cambio (vale, hay excepciones, pero en esos casos esa arquitectura abierta es un requisito de nivel superior).

Al utilizar EF tiene varias opciones cómo crear entidades:

  • herramienta de uso cutom para generar objetos Entity. Este es el enfoque predeterminado que crea el archivo "código detrás" para EDMX. Es la única solución disponible en EFv1 (.NET 3.5 SP1).
  • Utilice las plantillas T4 para generar objetos Entity, POCO, STE o cualquier tipo de entidad personalizada (puede modificar la lógica de generación). Esto se usa a menudo con EFv4.
  • Escriba POCO por ustedes mismos. Esto se puede usar con EFv4 y siempre se usa con el primer acercamiento de código en EF 4.1.

Si espera que la tecnología de acceso a datos pueda cambiar en el futuro, utilice el segundo o el tercer enfoque con POCO. En el caso de las plantillas T4, puede simplemente copiar las POCO generadas o modificar un archivo de proyecto para que no las pierda después de eliminar el archivo EDMX.

Si no está seguro de si alguno de segundo o tercer enfoque se adapte a comprobar mis respuestas a estas preguntas:

Porque de alguna manera estoy de acuerdo con @ respuesta de Patko se también debe marcar Ayende's blog. Escribió varias publicaciones sobre el uso excesivo de repositorios y sobre aplicaciones de arquitectura. Está escribiendo sobre NHibernate, pero se pueden tomar decisiones similares con EF. La única diferencia es que NHibernate ofrece una mejor abstracción, por lo que el código que usa NHibernate directamente es mejor comprobable.

+0

@Ladislav Mrnka Primero tengo que estar en desacuerdo con "No diseñe su aplicación porque algo puede suceder". Siempre trato de hacer que mi código sea robusto y defensivo, y por lo general prueba como una buena decisión más adelante. Pocas líneas adicionales significan horas ahorradas en refactorización y depuración. Si "No diseñar su aplicación debido a que algo puede suceder" era cierto, no muchos proyectos usarían repositorios en absoluto (excepto aquellos que necesitan soportar 2 tecnologías de almacenamiento persistentes desde el principio). En segundo lugar, me siento mal por pasar la referencia al contexto a la capa de Servicio, así que necesito algo de DAL para envolverlo. – drasto

+0

@Ladislav Mrnka +1 para plantillas T4 y esos enlaces. Algunos más recursos sobre eso? – drasto

+1

@drasto: si tiene la habilidad suficiente para tomar una decisión profesional sobre su arquitectura, entonces el enfoque está bien. Pero después de responder y leer muchas preguntas sobre EF y repositorios, simplemente creo que muchos desarrolladores están diseñando sus aplicaciones. Tener dos tecnologías de acceso a datos desde el principio es una buena razón para introducir repositorios, pero no lo mencionó en la pregunta. –

3

Una de las nuevas funciones en Entity Framework versión 4 es el desarrollo "Code First". Esto le permitirá usar clases regulares de C# (POCO) con el marco de la entidad. Una vez que sus clases estén escritas de esta manera, podría escribir una implementación diferente del repositorio que persista esas clases utilizando un mecanismo diferente.

ScottGu tiene un blog post que contiene más información.

+1

Actualmente no es la función de EFv4. Es una versión separada llamada EF 4.1. –

+0

+1 Me gusta. No solo porque tengo clases independientes sino también porque puedo recrear bases de datos cada vez que hago cambios en las clases de modelos. Sin embargo, hay algo que no me gusta, es decir, tener que escribir todas las clases y sus propiedades. Espero que mi modelo tenga entre 50 y 70 clases. En el diseñador visual se ve mucho mejor. Así que esperaba algo como "1. crear un diagrama de modelo visual 2. tener VS generar clases de POCO desde el diagrama 3. Tener EF para generar tablas de clave externa, etc. de clases de POCO o (incluso mejor) tener alguna otra herramienta generar diagrama de EF de POCO clases " – drasto

+0

@drasto - Una crítica común con el diseñador de EF es lo difícil que es usar con una buena cantidad de entidades. Es extraño que tengas el problema opuesto. @Sean Reily - Tu respuesta es incorrecta. "Code First" en 4.1 no le permitió usar las clases de POCO, esto fue posible de forma predeterminada en 4.0. MS luego lanzó las plantillas t4 que hicieron esto más fácil. http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313 – jfar

7

Tener la capacidad de cambiar de una tecnología de persistencia a otra es bueno y todo, pero ¿realmente lo necesita?

Antes que nada, ¿qué es un repositorio? By Fowler's definition proporciona un acceso similar a una colección en memoria a objetos de dominio. Pero cada herramienta moderna de ORM ya lo hace, por lo que otro nivel de abstracción simplemente agrega un poco más de complejidad.

En segundo lugar, el cambio de una tecnología de persistencia a otra suele ser más complejo que simplemente proporcionar otra implementación de repositorio. Por ejemplo, ¿cómo piensa manejar las transacciones? Las transacciones generalmente dependen del contexto y se manejan fuera de los repositorios. Por supuesto, podría utilizar algún tipo de implementación de unidad de trabajo, pero luego tendría que implementar una nueva unidad de trabajo para cada tecnología de persistencia.

No quiero decir que no deba usar repositorios, solo que tal vez lo piense otra vez.

+0

Todavía estoy considerando mis opciones. Tengo una aplicación ASP.NET MVC donde la persistencia solo quiere funcionar ... Está realmente mal diseñada. Así que tendré que reconstruirlo desde cero esta vez correctamente y de la manera que me permita cambiar fácilmente el modelo de acuerdo con las necesidades de lógica de negocios en desarrollo (que estoy trabajando en este momento). Entonces, ¿qué sugieres que haga? ¿Debería pasar una instancia de 'ObjectContext' a los servicios en la capa de servicio? Me siento algo mal por eso ... – drasto

+2

+1 porque estoy de acuerdo con eso. El repositorio se usa en exceso y se definió antes de que existieran las herramientas modernas de ORM. –

+3

Quizás pueda consultar el blog de Ayende en http://ayende.com/Blog/default.aspx. Él fue uno de los proponentes del patrón de repositorio, pero cambió de opinión. Comenzó con esta http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx publicación de blog. Sus últimas publicaciones también brindan algunas ideas sobre cómo hacerlo. En cuanto a 'ObjectContext', no veo por qué no. Si pasara repositorios, ¿se sentiría mejor? Solo mira 'ObjectContext' como una especie de repositorio :) – Patko

6

Las clases de entidad creadas por el diseñador de EF están ahí en su proyecto, dentro de su "Model.Designer.cs". Puede copiar el código para que sus entidades permanezcan en su proyecto incluso si elimina su modelo o las referencias de EF. Sin embargo, están estrechamente relacionados con EF, por lo que debe esforzarse por desacoplar EF de las clases de entidad.

Hasta ahora, se había plantillas T4 que podrían ayudar con el desacoplamiento, pero aún requeriría algunos cambios en el T4 elegido:

  • ADO.NET EntityObject Generador
  • ADO.NET POCO Entidad Generador
  • ADO.NET Auto-Tracking Entidad Generador

EF4.1 aporta una API simplificada, DbContext, que mejora su experiencia con EF cuando desea desacoplar clases de entidad. Con EF4.1 obtiene 3 enfoques:

  • Código Primeros
    • crear las clases de EF y crea la base de datos como debe ser
    • clases no van a desaparecer cuando se quita las referencias a EF
    • que no tendrá que cualquier diseñador
  • primera base de datos
    • si ya dispone de una base de datos, se creará un modelo para usted en el diseñador
    • puede crear sus clases de entidad con la nueva plantilla T4 DbContext Generador
  • Modelo Primera
    • como ya lo hace en este momento, cree su modelo en el diseñador
    • puede crear clases de entidad con DbContext Generator

Ahora, respondiendo a la pregunta:

¿Cómo se quita esta dependencia?

  1. Instalar EF4.1
  2. Crear su modelo (utilizando el Modelo-primera aproximación)
  3. generar su base de datos de su modelo
  4. Generar sus clases de entidad con DbContext Generador

Vea cómo puede hacer todo esto aquí: EF 4.1 Model & Database First Walkthrough.
Debe leer la serie en ADO.NET Team Blog Using DbContext in EF Feature CTP5 Part 1: Introduction and Model(EF4.1 anteriormente se conocía como EF Feature CTP5).
Puede obtener más detalles en mi pregunta: EF POCO code only VS EF POCO with Entity Data Model.

+0

+1 Ahora mismo eres el claro ganador aquí. Decidí usar plantillas T4 para generar entidades POCO y luego tratar de descubrir cómo hacer que el marco vuelva a crear automáticamente las tablas de la base de datos cuando cambie el modelo. Pero me gusta su sugerencia más hasta ahora: parece que es más fácil hacerlo con API simplificada que con plantillas T4.Tengo una pregunta más: ¿es posible recrear automáticamente las tablas de mi base de datos junto con las clases POCO cada vez que cambio mi modelo cuando uso el enfoque Model First? Cómo puedo hacerlo ? – drasto

+0

Sé que la generación automática de tablas es posible para el primer acercamiento del código – drasto

+0

Le he hecho otra pregunta que se inspiró en su respuesta aquí, por favor siéntase libre de publicar alguna respuesta http://stackoverflow.com/questions/5410381/generate-poco-classes -from-model-using-t4-templates-vs-ef4-1-simplified-api-mode. Gracias de todos modos – drasto

Cuestiones relacionadas