2010-09-09 54 views
6

Tengo varios problemas al tratar de aplicar DDD con EF4 (en contexto ASP MVC2). Su ventaja sería muy apreciada.Cómo lidiar con DDD y EF4

En primer lugar, comencé a utilizar POCO porque la dependencia de ObjectContext no era muy cómoda en muchas situaciones.

Ir a POCO resolvió algunos problemas, pero la experiencia no es la que estaba acostumbrado con NHibernate.

Me gustaría saber si es posible usar el diseñador y generar no solo entidades sino también un objeto de valor (¿Tipo complejo?). Si me refiero a Value Object es una clase con un ctor sin propiedades establecidas (¿se necesita una modificación T4?).

La única forma que he encontrado de agregar comportamiento a entidades anémicas es crear clases parciales que amplíen las generadas por edmx. No estoy satisfecho con este enfoque.

No sé cómo crear varios repositorios con un solo edmx. Por ahora estoy usando un método de clases parciales a grupales para cada agregado. Cada grupo es un repositorio de hecho.

La última pregunta es sobre IQueryable. ¿Debería estar expuesto fuera del repositorio? Si me refiero al libro ble, el repositorio debe ser una unidad de ejecución y no debe exponer algo como IQueryable. Qué piensas ?

Gracias por su ayuda.

Thomas

+1

En cuanto a la pregunta de IQueryable, consulte esto: http://stackoverflow.com/questions/1699607/asp-mvc-repository-that-reflects-iqueryable-but-not-linq-to-sql-ddd-how-to -ques/1699756 # 1699756 –

Respuesta

0

Ha pasado un tiempo desde que hice esa pregunta y tuve la oportunidad de hacerlo por mi cuenta.

No creo que sea una buena práctica exponer IQueryable fuera de la capa DAL. Trae más problemas que soluciona. Estoy hablando de grandes aplicaciones MVC. En primer lugar, las refactorizaciones son más difíciles, muchos desarrolladores utilizan instancias IQueryable a partir de las vistas y después de luchar con el hecho de que al resolver IQueryable la conexión ya estaba eliminada. Problemas de rendimiento porque a menudo se consulta toda la base de datos para un conjunto dado de resultados, etc.

Prefiero exponer Iumerable de mis repositorios y créanme, me ahorra muchos problemas.

4

Está bien usar POCOs, pero tenga en cuenta que EntityObject no requiere una ObjectContext.

Sí, los tipos complejos son objetos de valor y sí, puede generarlos en el diseñador. Seleccione varias propiedades de una entidad, haga clic con el botón derecho y elija refactorizar en tipo complejo.

Recomiendo poner métodos comerciales en sus propios tipos, no en entidades. Los tipos "anémicos" pueden ser un problema si debe mantenerlos, pero cuando están codificados no son un problema de mantenimiento. Hacer que la lógica comercial se separe de los tipos de entidad permite que las reglas de su negocio y su modelo de datos evolucionen de manera independiente. Sí, debe usar clases parciales si debe mezclar estas preocupaciones, pero no creo que separar su modelo y sus reglas sea algo malo.

creo que los repositorios deben exponer IQueryable, pero se puede hacer un buen caso de que los servicios de dominio no debería. La gente a menudo intenta construir sus repositorios en servicios de dominio, pero recuerda que el repositorio existe solo para abstraer la persistencia. Preocupaciones como la seguridad deben estar en los servicios de dominio, y puede argumentar que tener IQueryable le da demasiada potencia al consumidor.

+0

Gracias por su respuesta. Generaly pongo métodos de comportamiento obvios a las entidades. Cuando no es obvio, creo un servicio para eso. ¿Cómo resuelves ese punto? Si los repositorios exponen IQueryable por lo que no hay garantía de que se eliminará en cualquier momento o si se elimina, habrá problemas al convertir Iqueryable a List o Enumarable porque la conexión ya estará cerrada. –

+0

En cuanto a la eliminación de conexiones, la cara pública de mis servicios de dominio es una unidad de objeto de trabajo. La unidad de trabajo implementa IDisposable. La unidad de trabajo mantiene una referencia privada a una instancia de ObjectContext que se pasa a los repositorios mediante la inyección del constructor. En mi caso, la unidad de trabajo es consumida por los controladores MVC de ASP.NET, que no se eliminan hasta que se visualizan las vistas, etc. Por lo tanto, deshacerse de todo en el momento correcto es bastante natural; Nunca tengo que pensar en eso. –

+0

En cuanto a dónde poner los métodos comerciales, me resulta mucho más natural poner todo en servicios de dominio en lugar de algunos en servicios de dominio y otros en diferentes lugares. Esto es especialmente importante cuando utiliza servicios de datos como ADO.NET data services/Astoria. –

1

Creo que está bien exponer IQueryable fuera del repositorio, solo porque no hacerlo podría ser innecesariamente restrictivo. Si solo expone los datos a través de métodos como GetPeopleByBirthday y GetPeopleByLastName, ¿qué sucede cuando alguien va a buscar a una persona con el apellido y? ¿Atraes a todas las personas con el apellido "Smith" y haces una búsqueda lineal del cumpleaños que deseas, o creas un nuevo método GetPeopleByBirthdayAndLastName? ¿Qué hay del pobre tipo desventurado que tiene que implementar un formulario QBE?

Cuando la única manera de hacer consultas ad hoc contra el dominio era generar SQL, la única forma de mantenerse a salvo era ofrecer solo métodos específicos para recuperar y cambiar datos. Ahora que tenemos LINQ, sin embargo, no hay razón para mantener las esposas. Cualquiera puede enviar una consulta y puede ejecutarla de manera segura y sin preocupaciones.

Por supuesto, podría estar preocupado de que un usuario pueda ver los datos de otra persona, pero eso es fácil de mitigar porque puede restringir los datos que proporciona. Por ejemplo:

public IQueryable<Content> Content 
{ 
    get { return Content.Where(c => c.UserId == this.UserId); } 
} 

Esto se asegurará de que las únicas filas Content que el usuario puede obtener son los que tienen su UserId.

Si su preocupación es la carga en la base de datos, podría hacer cosas como examinar expresiones de consulta para escaneos de tabla (accediendo a tablas sin Where cláusulas o sin columnas indexadas en la cláusula Where). Por supuesto, eso no es trivial, y yo no lo recomendaría.