Dao, Repository y clases Query

37 views
Skip to first unread message

JoseFR

unread,
May 13, 2009, 2:11:54 PM5/13/09
to AltNet-Argentina
Hacia el final de la sesión sobre arquitectura, silverlight, wcf y no
me acuerdo mas... Se armo una discusión sobre el tema de los
repositorios:

interface IRepositoryDeAlgo{
FindAll()
Get(object id)
FindByNameAndLastNameAndAddressOrderedByNameThenByLastNameDESC
(Name, LastName, Address)
....
}


Era una exageración el último méodo.

Según vengo leyendo (en Fawler) esto sería mas un dao que repository.
Aunque tengo para citar varios links y productos donde ambos terminos
se usan indiferentemente.

Me gustaría si a alguien le interesa continuar el debate por este
medio

Por otro lado, recientemente hubo un poco de ruido por unos post que
saco Ayende en donde mato al repositorio.

¿Qué opina usted?

Leonardo Micheloni

unread,
May 13, 2009, 2:18:39 PM5/13/09
to altnet-a...@googlegroups.com

Mi forma de verlo es: si es necesario se hace y lo llamo como sea, me parece que hay gente ortodóxa y gente productiva, tampoco estamos metiendole una patada a las tablas de Moises :), es decir (y de paso metiendo a Ayende) si Moq llama a todo igual sea mock o stub o algo, no importa, mi objetivo es hacer un test de unidad si para usar Rhino tengo que pensar si va un dynamic, un stub y mock....no sé, yo me dedico a escribir software no a profesar la palabra :P 

PD: Me puse en modo "debate"

Jorge E. Fioranelli

unread,
May 13, 2009, 2:22:22 PM5/13/09
to altnet-a...@googlegroups.com
Lo que yo traté de explicar en la discusión del sábado es que tratamos que todos los querys de linq queden dentro del repositorio, para poder separar bien las responsabilidades y no se pueda pedir cualquier cosa desde las entidades.
 
A lo que kzu respondió: "si las entidades necesitan algo, vas a tener que modificar el repositorio igual".
 
Lo cual es totalmente verdad, pero así y todo fuerzo que "lo piensen dos veces".
 
Jorge

De: altnet-a...@googlegroups.com [altnet-a...@googlegroups.com] En nombre de Leonardo Micheloni [leonardogabr...@gmail.com]
Enviado el: miércoles, 13 de mayo de 2009 03:18 p.m.
Para: altnet-a...@googlegroups.com
Asunto: [altnet-argentina] Re: Dao, Repository y clases Query

"José F. Romaniello"

unread,
May 13, 2009, 2:31:56 PM5/13/09
to altnet-a...@googlegroups.com
En un proyecto de hace unos meses tengo algo así:

Public class DaoPersona<Persona> : Repository<Persona>, IRepo....blabla

No me he puesto a pensar que es cada una concretamente..

Pero cual fue mi criterio para llegar a eso?
La palabra "DaoPersona" es mas corta y me sonaba mejor que
"RepositoryPersona".. Y cualquier otro intento como "RepPersona".

No se si es por mis costumbres de vb6...A lo que voy es que mas alla del
nombre que le pongamos, lo que a mi me interesa ver son las distintas
formas de encarar el problema... Y si le ponemos nombres a las cosas
creo que nos podemos llegar a entender mejor.




Leonardo Micheloni escribió:
>
> Mi forma de verlo es: si es necesario se hace y lo llamo como sea, me
> parece que hay gente ortodóxa y gente productiva, tampoco estamos
> metiendole una patada a las tablas de Moises :), es decir (y de paso
> metiendo a Ayende) si Moq llama a todo igual sea mock o stub o algo,
> no importa, mi objetivo es hacer un test de unidad si para usar Rhino
> tengo que pensar si va un dynamic, un stub y mock....no sé, yo me
> dedico a escribir software no a profesar la palabra :P
>
> PD: Me puse en modo "debate"
>
>
> On 5/13/09, *JoseFR* <jfroma...@gmail.com

Pablo Zaidenvoren

unread,
May 13, 2009, 2:34:17 PM5/13/09
to altnet-a...@googlegroups.com
Repository es sumamente práctico en el caso de que quieras dejar
uniforme el acceso a datos, pudiendo hacer controles mucho mas
genericos que los consuman.
Ejemplo típico: ABMs (semi) automáticos, grillas con filtros,
paginacion, etc y algunas cosas mas.

Ahora, si en tu proyecto cada módulo es un mundo, no creo que sea el
camino a seguir.

Saludos!
Z

2009/5/13 Jorge E. Fioranelli <jor...@lagash.com>:
--
Z
http://zPod.com.ar

Daniel Cazzulino

unread,
May 13, 2009, 3:05:37 PM5/13/09
to altnet-a...@googlegroups.com
lo critico de todo esto es que si usas la palabra Repository, la clase de dominio se deberia llamar Person, y sino deberia ser Repositorio y Persona:

Repository<Person>
Repositorio<Persona>

spanglish todo mezclado siempre queda horrible.

Esto es el Spanglish Anti-Pattern :P

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/13 "José F. Romaniello" <jfroma...@gmail.com>

"José F. Romaniello"

unread,
May 13, 2009, 3:18:07 PM5/13/09
to altnet-a...@googlegroups.com
No estoy de acuerdo con lo que decís. Para el ejemplo que dí si.
Creo que en mi caso es un anti-pattern forzado.

No me puedo sacar el español de encima si tengo cosas en el dominio
como "Retención de Ingresos Brutos" aunque tiene una traducción en
ingles, me es muy poco natural cuando el día de mañana me llega una
modificación tener que ponerme a buscar como se decía en ingles "AH!!!
retention revenue gross tax cochicochi"

Por otro lado, es evidente que no puedo deshacerme del ingles.
Casualmente el proyecto que mencionaba estaba usando un repository que
no había creado yo, era heredado de un fw en ingles..
y aunque ahora tengo mi Repositorio... Siempre voy a tener

if ( retencion.Equals(....) )

Ojo para un sistema de personas y mascotas, probablemente lo hago todo
en ingles (si es que alguna vez me llegara a tocar).

Daniel Cazzulino escribió:
> lo critico de todo esto es que si usas la palabra Repository, la clase
> de dominio se deberia llamar Person, y sino deberia ser Repositorio y
> Persona:
>
> Repository<Person>
> Repositorio<Persona>
>
> spanglish todo mezclado siempre queda horrible.
>
> Esto es el Spanglish Anti-Pattern :P
>
> /kzu
>
> --
> Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1
> 425.329.3471
>
>
> 2009/5/13 "José F. Romaniello" <jfroma...@gmail.com
> <mailto:jfroma...@gmail.com>>
> > <mailto:jfroma...@gmail.com <mailto:jfroma...@gmail.com>>>

Dario Quintana

unread,
May 13, 2009, 3:21:29 PM5/13/09
to altnet-a...@googlegroups.com
Hola gente.

FindAll, hay veces que no se usa, imposible aplicar a Personas, Facturas o Compras, y si llegas a ver en el repositorio un FindAll de Facturas o Compras es como para cortar extremidades del programador a cargo (no estoy hablando de las manos y pies).
Get(object id) un poco trivial y si usás Nh haces session.Get<Persona>(5) y listo.
FindByNameAndLastNameAndAddressOrderedByNameThenByLastNameDESC: hasta parece un chiste, pero yo ví cosas así. Para mi esto tiene que ir en un objeto distinto, seteás criterios de filtrado y disparás la query. Dependiendo el fwk esto se hará de una manera u otra.

Desarmé todo el Repositorio, y al final dentro de mi aplicación no lo necesito. Y si alguien dice: "Pero no usás Unit-Testing?, como hacés para mockear el Repositorio que no tenés y testear la App?". Me gusta testear contra el motor de base de datos, a lo sumo para agilizar el día a día se hará contra una InMemory-Database como Sqlite, y al final del día testear contra el rdbms más cercano a producción, hay fws que permiten hacer esto :-)

No leí el post de Ayende que habla sobre esto che.

2009/5/13 JoseFR <jfroma...@gmail.com>



--
Dario Quintana
http://darioquintana.com.ar

Daniel Cazzulino

unread,
May 13, 2009, 3:34:43 PM5/13/09
to altnet-a...@googlegroups.com
si tenes un fx para definir los repositorios, estas en un problema ;)

a lo q voy es q es feo tener algo tipo Persona.FirstName o cosas similarmente entreveradas.

"José F. Romaniello"

unread,
May 13, 2009, 3:39:56 PM5/13/09
to altnet-a...@googlegroups.com
> si tenes un fx para definir los repositorios, estas en un problema ;)
Si estaba usando uno de otro lado y lo deje de usar por un par de
complicaciones que tuve.

> a lo q voy es q es feo tener algo tipo Persona.FirstName o cosas
similarmente entreveradas.
No! a esa chanchada no llegue... El dominio esta en español.


Daniel Cazzulino escribió:
> si tenes un fx para definir los repositorios, estas en un problema ;)
>
> a lo q voy es q es feo tener algo tipo Persona.FirstName o cosas
> similarmente entreveradas.
>
> /kzu
>
> --
> Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1
> 425.329.3471
>
>
> 2009/5/13 "José F. Romaniello" <jfroma...@gmail.com
> <mailto:jfroma...@gmail.com>>
> > <mailto:jfroma...@gmail.com <mailto:jfroma...@gmail.com>>>

Dario Quintana

unread,
May 13, 2009, 3:49:34 PM5/13/09
to altnet-a...@googlegroups.com
A lo que iba cuando decía que había fwks para eso, me refería a que te permiten intercambiar contra qué base de datos trabajas, y podés testear tranquilamente contra un sqlite-inmemory y para asegurarte corrés la suite contra un sql Server.

Lo que decís de las cosas entreveradas como Persona.FirstName, estoy de acuerdo, no es lindo.

2009/5/13 Daniel Cazzulino <kzu.net@gmail.com>
si tenes un fx para definir los repositorios, estas en un problema ;)

a lo q voy es q es feo tener algo tipo Persona.FirstName o cosas similarmente entreveradas.

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


Daniel Cazzulino

unread,
May 13, 2009, 4:12:00 PM5/13/09
to altnet-a...@googlegroups.com
Si tenes un repositorio q expone IQueryable<T> para tus entities, ni necesitas una base. Un List<T> es suficiente para mocking/stubbing :)


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/13 Dario Quintana <cont...@darioquintana.com.ar>

"José F. Romaniello"

unread,
May 13, 2009, 5:51:50 PM5/13/09
to altnet-a...@googlegroups.com
Me encanta esa opción. A mi query object le meto un list y verifico el
resultado.
Creo que esa es una gran bondad de linq.

Daniel Cazzulino escribió:
> Si tenes un repositorio q expone IQueryable<T> para tus entities, ni
> necesitas una base. Un List<T> es suficiente para mocking/stubbing :)
>
> /kzu
>
> --
> Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1
> 425.329.3471
>
>
> 2009/5/13 Dario Quintana <cont...@darioquintana.com.ar
> <mailto:cont...@darioquintana.com.ar>>
>
> A lo que iba cuando decía que había fwks para eso, me refería a
> que te permiten intercambiar contra qué base de datos trabajas, y
> podés testear tranquilamente contra un sqlite-inmemory y para
> asegurarte corrés la suite contra un sql Server.
>
> Lo que decís de las cosas entreveradas como Persona.FirstName,
> estoy de acuerdo, no es lindo.
>
> 2009/5/13 Daniel Cazzulino <kzu.net <http://kzu.net>@gmail.com
> <http://gmail.com>>

Germán Schuager

unread,
May 13, 2009, 8:32:17 PM5/13/09
to altnet-a...@googlegroups.com
Buenas.

Lo que dice Ayende es que la abstracción del repositorio no te brinda ninguna ventaja a usar directamente NH (o cualquier otro ORM). Basicamente lo mismo que estás diciendo acá.

http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx

Me gustaría saber que piensan sobre esto.


2009/5/13 Dario Quintana <cont...@darioquintana.com.ar>

Jose Ramirez

unread,
May 13, 2009, 5:27:46 PM5/13/09
to altnet-a...@googlegroups.com
@kzu

No estoy de acuerdo, una cosa es el dominio que tiene que estar en el idioma del dominio, o mejor dicho en el idioma que usan los expertos del dominio. Otra cosa son tus artefactos de soft, que generalmente van a estar en ingles.

Con respecto al uso del Repository, durante bastante tiempo lo considere a los repositorios genericos como la salvacion, luego de a poco fui cambiando de idea y ahora me gustan mas los servicios bien dedicados y explicitos.

Por ultimo, con respecto al session.Get<Entidad>(id) generalmente no podes usarlo porque el cliente maneja el id de negocio (lo que yo llamo BizId) que es un string unique y no puedo hacer Get por él. Lo que termine haciendo es un extended method sobre Isession GetByBizId<T>(string bizId) que hace un query, no me quedó otra. A uds no les pasa?

saludos
 
Ing. Jose Ramirez
MCTS
http://www.josehr.com.ar

Fabio Maulo

unread,
May 14, 2009, 2:39:07 AM5/14/09
to altnet-a...@googlegroups.com
El 13 de mayo de 2009 21:32, Germán Schuager <gsch...@gmail.com> escribió:

Me gustaría saber que piensan sobre esto.

Pienso que es una provocación.
1) IQueryable<T> no resuelve todo y de todas formas implica que hay que tener algo que lo transforme a SQL
2) Si se tiene algo que transforma IQueryable<T> o mejor dicho un ExpressionTree en SQL se puede permitir que quien programe capa exteriores al acceso a datos usen LINQ pero sin extensiones especifica de una implementación especifica de un acceso a datos (por eso no resuelve todo)
3) Mocking de DB o RDBMS en RAM no sirven si lo que se está testeando es el acceso a datos
4) Un DAO/Repository se puede mockear solo si es "query-closed" o sea si las queries las arman los DAO/Repository de lo contrario jamas podras crear tests de optimización de acceso a datos.

Estas son algunas de mi opiniones... escribo yo y no me queda otra que escribir mis opiniones.
--
Fabio Maulo

Leonardo Micheloni

unread,
May 14, 2009, 8:11:50 AM5/14/09
to altnet-a...@googlegroups.com
Cuando vamos a usar bases de datos orientadas a objetos :) ??? o el motor va a tener esto resuelto a bajo nivel?? ya lo sé, no es fácil, pero un día hay que empezar, me parece que las base de datos relacioneles son como los autos con motor de combustión interna, no cambiaron casi nada en 40 años y se extendieron tanto que es muy difícil pensar en tirar la inversión para cambiarlos, por otro lado los motores eléctricos....que poco ruido hacen y que poco contaminan el entorno.....

Daniel Cazzulino

unread,
May 14, 2009, 9:01:36 AM5/14/09
to altnet-a...@googlegroups.com
El punto q falta en el rompecabezas es donde pones los queries q no van a estar mas en el repositorio. Obviamente no pueden estar desparramados como expresiones LINQ custom desparramadas por todo tu codigo.

Ahi es donde entra en command-query separation, q ese SI testeas contra la DB posta, para ver como funca y que FUNQUE. Y ese es un extension method sobre un IQueryable<T>, asi q los tests de q andan contra una List<T> ya los tenes en tus unit tests de todo, y los de q andan con la DB los tenes como standalone.

Igualmente para mi necesitas correr los tests en modo integracion (pegandole a la DB posta) donde cableas todo, pero ese no seria parte del CI ni de la corrida q haces en TDD, porq llevaria mucho tiempo.


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/14 Fabio Maulo <fabio...@gmail.com>

Rodolfo Finochietti

unread,
May 14, 2009, 9:14:43 AM5/14/09
to altnet-a...@googlegroups.com
Amen!!!
 
Estuve pensando un poco en el tema, y sigo pensando que con solamente exponer IQueryable no alcanza, por que además de los puntos que describe Fabio (con los que estoy 100% de acuerdo), tampoco me cierra en términos de separación de responsabilidades.
 
Pero probablemente hay algo que no estoy viendo, kzu podes ampliar la idea?
 

From: altnet-a...@googlegroups.com [altnet-a...@googlegroups.com] On Behalf Of Fabio Maulo [fabio...@gmail.com]
Sent: Thursday, May 14, 2009 03:39
To: altnet-a...@googlegroups.com
Subject: [altnet-argentina] Re: Dao, Repository y clases Query

Germán Schuager

unread,
May 14, 2009, 9:20:24 AM5/14/09
to altnet-a...@googlegroups.com
La propuesta del post no es ni siquiera usar IQueryable<T> sino directamente la API de NH, ahí no habría problema con lo de "extensiones especifica de una implementación especifica de un acceso a datos".

Los queries los encapsula en query objects que contienen un método que recibe una ISession y devuelve una ICriteria por ej, ahí si querés "adornar" ese resultado para especificar fetching, paging, etc. no tendrías ningún inconveniente.

El problema con esta metodología es que NH (o lo que fuere) se filtra en todas las capas de tu aplicación (no se si es realmente un problema) y que al no tener un IRepository no lo podés mockear :) y tenes que testear si o si contra una BD.

Aunque hasta ahora vengo usando el repository pattern en varios lugares, me está entrando la duda sobre si es conveniente (que ventajas tiene) abstraer el ORM detras de IRepository.


2009/5/14 Fabio Maulo <fabio...@gmail.com>

Dario Quintana

unread,
May 14, 2009, 9:54:03 AM5/14/09
to altnet-a...@googlegroups.com
Siempre por tener un entorno de testing parecido a producción, testeo contra el mismo tipo de RDBMS, creo que es lo mejor.

Pero si que va lento el tema, pienso que podés optar en el día: correr los tests contra un esquema de correr los tests contra un RDBMS como sqlite en ram, finalizando el día, podés cambiar la configuración contra un SQL Server o Postgre. Todavía nunca lo usé a este esquema, pero hay gente que si.

2009/5/14 Fabio Maulo <fabio...@gmail.com>


3) Mocking de DB o RDBMS en RAM no sirven si lo que se está testeando es el acceso a datos

Daniel Cazzulino

unread,
May 14, 2009, 10:10:39 AM5/14/09
to altnet-a...@googlegroups.com
Cuales serian las reponsabilidades del repositorio? Empecemos por lo basico.
Y el punto es si es responsable de queries o no.


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/14 Rodolfo Finochietti <rodo...@lagash.com>

Daniel Cazzulino

unread,
May 14, 2009, 10:18:10 AM5/14/09
to altnet-a...@googlegroups.com
(no soy usuario de NH, aclaro) no entiendo porq si tenes un ISession y un ICriteria q se devuelve, eso no se podria mockear ...

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/14 Germán Schuager <gsch...@gmail.com>

Germán Schuager

unread,
May 14, 2009, 10:25:08 AM5/14/09
to altnet-a...@googlegroups.com
Si, es verdad; igual es más comodo mockear un IRepository que la API de NH.

Raul Lopez

unread,
May 14, 2009, 9:46:50 AM5/14/09
to altnet-a...@googlegroups.com
El mié, 13-05-2009 a las 18:27 -0300, Jose Ramirez escribió:
> @kzu
>
>
> No estoy de acuerdo, una cosa es el dominio que tiene que estar en el
> idioma del dominio, o mejor dicho en el idioma que usan los expertos
> del dominio. Otra cosa son tus artefactos de soft, que generalmente
> van a estar en ingles.
>
Comparto
>
> Con respecto al uso del Repository, durante bastante tiempo lo
> considere a los repositorios genericos como la salvacion, luego de a
> poco fui cambiando de idea y ahora me gustan mas los servicios bien
> dedicados y explicitos.

En lo personal me queda comodo tener en algun lado (Dao/Repository)
clases que envuelvan el uso de nh.
Y si... me queda cocoliche (como dice Fabio) algo como PersonaDao pero
me la banco.
>
>
> Por ultimo, con respecto al session.Get<Entidad>(id) generalmente no
> podes usarlo porque el cliente maneja el id de negocio (lo que yo
> llamo BizId) que es un string unique y no puedo hacer Get por él. Lo
> que termine haciendo es un extended method sobre Isession
> GetByBizId<T>(string bizId) que hace un query, no me quedó otra. A uds
> no les pasa?

Si, y llegue a la misma solucion.

Saludos,
Raul.
>
> saludos
>
> Ing. Jose Ramirez
> MCTS
> http://www.josehr.com.ar
>
>
> 2009/5/13 Daniel Cazzulino <kzu...@gmail.com>

Fabio Maulo

unread,
May 14, 2009, 11:41:17 AM5/14/09
to altnet-a...@googlegroups.com
El 14 de mayo de 2009 10:20, Germán Schuager <gsch...@gmail.com> escribió:

El problema con esta metodología es que NH (o lo que fuere) se filtra en todas las capas de tu aplicación (no se si es realmente un problema) y que al no tener un IRepository no lo podés mockear :) y tenes que testear si o si contra una BD.

No gracias.
Prefiero que NH este solo y exclusivamente en los DAOs/Repository.
Cuando funcione EF quisiera estar listo para usarlo.
--
Fabio Maulo

Germán Schuager

unread,
May 14, 2009, 11:48:02 AM5/14/09
to altnet-a...@googlegroups.com
O sea que tu motivación para abstraer NH detrás de IRepository sería que en algún momento quisieras cambiar de ORM en una aplicación previamente desarrollada?

(Aclaración: yo también estoy trabajando de esta forma actualmente, pero como que me entran dudas de si es necesario)

2009/5/14 Fabio Maulo <fabio...@gmail.com>

Daniel Calvin

unread,
May 14, 2009, 11:54:15 AM5/14/09
to altnet-a...@googlegroups.com
Una duda gente...

Alta cohesion y Bajo acoplamiento no son motivos suficientes... digo...  no?

:))

Daniel Calvin
--
Daniel A. Calvin
Cooperator Team Member
http://www.cooperator.com.ar
Microsoft Certified Professional

"José F. Romaniello"

unread,
May 14, 2009, 12:35:13 PM5/14/09
to altnet-a...@googlegroups.com
Comparto esto que dice Fabio, aunque nunca cambie a EF este proyecto.
Yo les cuento mi forma de verlo:

Tengo un IRepository<T> y un Repository<T> "UNICA CLASE" que implementa
IRepository<T>.
No hay ninguna otra clase que hereda de Repository<T>
-> (remarco esto, no hay PersonRepository : Repository<Person>)

IRepository<T> es queryable .. pero tiene otros metodos para crear,
actualizar y eliminar..

Por otro lado tiene un metodo GetByQuery(ISimpleQuery simpleQuery) y un
GetByQuery(IComplexQuery complexQuery)

ISimpleQuery tiene un metodo: IQueryable<T> GetQuery(IQueryable<T> query).
IComplexQuery tiene un metodo: IQueryable<T> GetQuery(ISession session).


Si necesito hacer una query mas compleja en la que no puedo utilizar
IQueryable directamente implemento IComplexQuery y uso el objeto UoW del
ORM. Si fuera nh usaría hql o criteria.
Trato de hacer las queries a partir de Iqueryable es decir implementando
ISimpleQuery.

Mi fw de IoC inyecta IRepository<Person> en mis controllers lo cual me
deja hacer

rep.FindAll()... rep.Save(person) y rep.GetByQuery(new SlicedQuery(.....))

thoughts?


Fabio Maulo escribió:
> El 14 de mayo de 2009 10:20, Germán Schuager <gsch...@gmail.com
> <mailto:gsch...@gmail.com>> escribió:

Mauricio Miraglio

unread,
May 14, 2009, 12:44:06 PM5/14/09
to altnet-a...@googlegroups.com
Hace unos días leí este artículo que da algunos tips, o al menos, cosas en las qué pensar al momento de diseñar estos repositorios genéricos.

DDD: The Generic Repository

Saludos.

Mauricio.

2009/5/14 "José F. Romaniello" <jfroma...@gmail.com>

Raul Lopez

unread,
May 14, 2009, 12:52:23 PM5/14/09
to altnet-a...@googlegroups.com
y.... para mi que si.

Fabio Maulo

unread,
May 14, 2009, 1:32:16 PM5/14/09
to altnet-a...@googlegroups.com
A mi me gustó mas lo que me dijo AjL hace unos años...
"Poné NH donde menos te va a doler"
Por eso está en un DAOs, allí quieto.
--
Fabio Maulo

Fabio Maulo

unread,
May 14, 2009, 1:38:56 PM5/14/09
to altnet-a...@googlegroups.com
Quisiera ver que pasa con las referencias cuando tengas un IComplexQuery ...
IRepository<T>.Find(IComplexQuery)
Si tenes una sola implementación quiero ver lo que pasa.
A parte eso...
Yo he visto IRepository<T>.Clear() y aún recuerdo la sensación de dolor que tuve en los h....


--
Fabio Maulo

Carlos Peix

unread,
May 14, 2009, 1:49:49 PM5/14/09
to altnet-a...@googlegroups.com
Ojos es sin H Fabio...

2009/5/14 Fabio Maulo <fabio...@gmail.com>:


> Quisiera ver que pasa con las referencias cuando tengas un IComplexQuery ...
> IRepository<T>.Find(IComplexQuery)
> Si tenes una sola implementación quiero ver lo que pasa.
> A parte eso...
> Yo he visto IRepository<T>.Clear() y aún recuerdo la sensación de dolor que
> tuve en los h....

--
Carlos Peix

"José F. Romaniello"

unread,
May 14, 2009, 2:09:45 PM5/14/09
to altnet-a...@googlegroups.com
Siguiendo con el ejemplo anterior este podría ser un caso:

public class GenericSlicedQuery<T> : IComplexQuery where T : class
{
public int Start { get; set; }
public int Limit { get; set; }

public ICriteria GetQuery(ISession session)
{
ICriteria criteria = session.CreateCriteria<T>();
criteria.SetFirstResult(Start).SetMaxResults(Limit);
return criteria;
}
}


Ya se, ICriteria e ISession estan en nh. Pero no implemento
IComplexQuery para cualquier pavada como esta.
Y si algún día necesito cambiar el ORM (lo cual no creo), voy a tener
que hacer alguna magia con el repositorio (su única implementación) y
con las "complex" queries, es decir con las queries que realice a partir
de una feature del orm... No queryable. Que eso lo voy a tener que hacer
cualquiera sea la implementación que realice.

(y repito: este es un caso en el que justamente no utilizaría complex y
probablemente tampoco simple)

Aca va una del otro tipo:

public class SlicedQuery<T> : ISimpleQuery<T> where T : class
{
public string Sort { get; set; }
public SortDirectionEnum SortDirection { get; set; }
public int? Limit { get; set; }
public int? Start { get; set; }

public IQueryable<T> GetQuery(ISession session)
{
IQueryable<T> result = session.Linq<T>();

if (!string.IsNullOrEmpty(Sort) &&
!string.IsNullOrEmpty(SortDirection))
result = SortDirection = SortDirectionEnum.ASC ?
result.OrderBy(Sort) : result.OrderByDescending(Sort);

if (Limit.HasValue && Start.HasValue)
result = result.Skip(Start.Value).Take(Limit.Value);


return result;
}
}

Esta utiliza unos extensions methods para iqueryable que permiten
ordenar por string en vez de lambda.

Carlos Peix escribió:

Rodolfo Finochietti

unread,
May 14, 2009, 2:20:55 PM5/14/09
to altnet-a...@googlegroups.com

Para mi es el responsable de las queries..



No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.329 / Virus Database: 270.12.26/2110 - Release Date: 05/12/09 06:22:00

cibrax

unread,
May 14, 2009, 2:28:18 PM5/14/09
to AltNet-Argentina
Creo que lo propone ayende es tener cada query es su respectiva clase
y no una clase repository con cientos de metodos por cada query. Lo
que en algunas casos tiene sentido.

Por ejemplo,

Una clase de repository unica seria,

public class CustomerRepository : ICustomerRepository
{
IQueryable<Customer> GetByName(string name)
}

Y una clase de query por cada metodo quedaria,

public class ActiveCustomerQuery : IQuery<Customer>
{
string Name;
IQueryable<Customer> GetQuery()
}

Devolver un IQueryable, brinda la suficiente flexibilidad a la UI para
poder aplicar paging u ordenar los resultados. La implementacion de
ActiveCustomerQuery para NH en el ejemplo de Ayende recibe en el
constructor tambien la session de NH (ISession). Pero eso queda dado
por cada implementacion.

Saludos.

On May 14, 3:09 pm, "José F. Romaniello" <jfromanie...@gmail.com>
wrote:
> > 2009/5/14 Fabio Maulo <fabioma...@gmail.com>:
>
> >> Quisiera ver que pasa con las referencias cuando tengas un IComplexQuery ...
> >> IRepository<T>.Find(IComplexQuery)
> >> Si tenes una sola implementación quiero ver lo que pasa.
> >> A parte eso...
> >> Yo he visto IRepository<T>.Clear() y aún recuerdo la sensación de dolor que
> >> tuve en los h....- Hide quoted text -
>
> - Show quoted text -

Fabio Maulo

unread,
May 14, 2009, 2:32:54 PM5/14/09
to altnet-a...@googlegroups.com
Yo veo ISession por todos lados e ISession es de NH.
Quien los llama a esos GetQuery ?
Desde donde vienen las implementaciones de IComplexQuery ?

Yo puedo entender algo tipo:
GenericSlicedQuery: IGenericSlicedQuery
con una ctor tipo
GenericSlicedQuery(ISessionFactory sf)
e una implementación tipo
IEnumerable<T> GetQuery()
{
var session = sf.GetCurrentSession();
.....
}

No quiero exponer ICriteria en ninguna capa.

Mirá... hay tres formas de no atar las capas externas a una implementación especifica de persistent-layer
- la mas vieja y usada es tener DAOs/Repositories que reciban un ICriterio<T> (notar que escribí CriteriO )
- otra es usar un repositorio de queries y pasar strings
- las mas nueva es usar lo que viene con .NET o sea pasar un Linq-ExpressionTree y que el DAO/Repository lo ejecute (y con esto agarrate Catalina si el persistent-layer no lo suporta de forma nativa).

Las solución que me gusta mas es la tercera pero la que usé hasta ahora es la primera.

Si el DAO/Repository recibe un Linq-ExpressionTree se la tiene que arreglar incluyendo su optimización para la persistencia así que si el Linq lo escribe un perro el resultado no debería cambiar. La transformación del ExpressionTree debería ser lo suficientemente intelligente de entender lo que convien ejecutar en el server y separarlo de lo que conviene ejecutar en el client luego; auto scala los queries.
--
Fabio Maulo

"José F. Romaniello"

unread,
May 14, 2009, 2:32:46 PM5/14/09
to altnet-a...@googlegroups.com
Otra cosa, IRepository<T>.Clear() no hay....
Las interfaces IEnumerable e IQueryable no tienen este método y tampoco
lo he agregado a IRepository<T>,

Carlos Peix escribió:

Rodolfo Finochietti

unread,
May 14, 2009, 2:36:55 PM5/14/09
to altnet-a...@googlegroups.com

100% de acuerdo.

 

From: altnet-a...@googlegroups.com [mailto:altnet-a...@googlegroups.com] On Behalf Of Fabio Maulo
Sent: jueves, 14 de mayo de 2009 15:33
To: altnet-a...@googlegroups.com
Subject: [altnet-argentina] Re: Dao, Repository y clases Query

 

Yo veo ISession por todos lados e ISession es de NH.

Fabio Maulo

unread,
May 14, 2009, 2:37:30 PM5/14/09
to altnet-a...@googlegroups.com
Yo puedo llegar a leer pero lo que propone no me interesó mucho.
Yo tengo clases de Criterios de interrogación; esas clases son a puro datos.
El DAO recibe un Criterios-de-interrogación, lo interpreta, se construye el query y devuelve los resultados o hace lo que tiene que hacer.
--
Fabio Maulo

Fabio Maulo

unread,
May 14, 2009, 2:49:55 PM5/14/09
to altnet-a...@googlegroups.com
Quiero ser un poco mas claro....
Fijate lo que le pasa a quien usa Rhino.Commons....
queres una banana ? bancate el casco, la rama, el mono encima la rama y la planta de bananas.
--
Fabio Maulo

Leandro Boffi

unread,
May 14, 2009, 2:50:24 PM5/14/09
to altnet-a...@googlegroups.com
Para mí la responsabilidad del repositorio es darnos una visión mas orientada a objetos de la persistencia.

Antes teníamos que usar SQL, por lo que era lógico encapsular la query dentro del repositorio, pero hoy en día que podemos hacer querys sobre objetos (Aunque al final sea SQL) no creo que sea una responsabilidad exclusiva del repositorio queriar.


El 14/05/09 15:20, "Rodolfo Finochietti" <rodo...@lagash.com> escribió:

"José F. Romaniello"

unread,
May 14, 2009, 2:54:16 PM5/14/09
to altnet-a...@googlegroups.com
Fabio Maulo escribió:
> Yo veo ISession por todos lados e ISession es de NH.
Yo no
> Quien los llama a esos GetQuery ?
*El **repositorio ejecuta el GetQuery de las clases queries **NADIE mas
*que el IRepositorio<T>. Nadie sabe que es un ICriteria excepto el único
repositorio que existe.
Ejemplo abreviado de metodo GetByQuery en Repository<T> (reitero unica
implementación de repositorio en todo el código)

public class Repository<T> : IRepository<T>
{
public IQueryable<T> GetByQuery(ISimpleQuery<T> query)
{
return query.GetQuery(Session);
}
}

Por lo tanto hablando en criollo en algún lugar podría tener esto:

AlgunRepositorio.GetByQuery(new SlicedQuery{Start = 1, Limit = 20})

> Desde donde vienen las implementaciones de IComplexQuery ?
>
> Yo puedo entender algo tipo:
> GenericSlicedQuery: IGenericSlicedQuery
> con una ctor tipo
> GenericSlicedQuery(ISessionFactory sf)
> e una implementación tipo
> IEnumerable<T> GetQuery()
> {
> var session = sf.GetCurrentSession();
> .....
> }
Aca estoy totalmente en desacuerdo, vos estas insinuando que una query
tiene la habilidad de "ejecutarse"... Esto es como decir que un cliente
tiene la habilidad de guardarse. No es muy OO friendly.
Para que sirve el repositorio entonces? Cito a Fawler :
"Client objects construct query specifications declaratively and submit
them to Repository for satisfaction."

>
> No quiero exponer ICriteria en ninguna capa.
>
> Mirá... hay tres formas de no atar las capas externas a una
> implementación especifica de persistent-layer
> - la mas vieja y usada es tener DAOs/Repositories que reciban un
> ICriterio<T> (notar que escribí CriteriO )
> - otra es usar un repositorio de queries y pasar strings
> - las mas nueva es usar lo que viene con .NET o sea pasar un
> Linq-ExpressionTree y que el DAO/Repository lo ejecute (y con esto
> agarrate Catalina si el persistent-layer no lo suporta de forma nativa).
>
> Las solución que me gusta mas es la tercera pero la que usé hasta
> ahora es la primera.
>
> Si el DAO/Repository recibe un Linq-ExpressionTree se la tiene que
> arreglar incluyendo su optimización para la persistencia así que si el
> Linq lo escribe un perro el resultado no debería cambiar. La
> transformación del ExpressionTree debería ser lo suficientemente
> intelligente de entender lo que convien ejecutar en el server y
> separarlo de lo que conviene ejecutar en el client luego; auto scala
> los queries.
>
> El 14 de mayo de 2009 15:09, "José F. Romaniello"
> <jfroma...@gmail.com <mailto:jfroma...@gmail.com>> escribió:
> <mailto:fabio...@gmail.com>>:

Fabio Maulo

unread,
May 14, 2009, 3:06:27 PM5/14/09
to altnet-a...@googlegroups.com
Sorry pero no entiendo
public IQueryable<T> GetByQuery(ISimpleQuery<T> query)
o sea que quien llama GetByQuery tiene que construir un ISimpleQuery<T>
la interface
ISimpleQuery<T>
tiene GetQuery(ISession) o sea que quien construye un ISimpleQuery<T> tiene que tener una referencia a NH

Eso es cuando el explorador está tirando de la banana y ya le apareció el casco de bananas, sigue tirando y le aparece una cosa peluda... y se da cuenta que es la mano del mono que está encima de la rama...
--
Fabio Maulo

Rodolfo Finochietti

unread,
May 14, 2009, 3:10:38 PM5/14/09
to altnet-a...@googlegroups.com

Eso no es tan así. Podemos hacer queries sobre objetos que se transforman en SQL solo para algunos casos. No hay providers de LINQ para todo (de hecho hay muy pocos providers de LINQ “terminados”).

 

Es cierto que en un sistema promedio se podría asumir que casi todo va a tener un provider de LINQ por detrás. Pero hay casos en los que no es así, y yo no quiero tener un modelo de arquitecta distinto para los casos en los que no.


 

No virus found in this incoming message.

"José F. Romaniello"

unread,
May 14, 2009, 3:17:23 PM5/14/09
to altnet-a...@googlegroups.com
Digamos que si "quien llama" quiere construir un ISimpleQuery y **usar
el método GetQuery** ahí le va a aparecer la rama, la banana, la
verdulería y don Tito el verdulero. Ah y un cartel que diga por favor si
quiere usar *este método* tiene que agregar las referencias a nh por que
yo no se que es un ISession ni un ICriteria..

Lo cual puede ser feo, muy feo, o no tan feo.. pero ¿estamos de acuerdo
que es así? Evidentemente no voy a usar GetQuery en otro lado que no sea
el repositorio.


Fabio Maulo escribió:
> Sorry pero no entiendo
> public IQueryable<T> GetByQuery(ISimpleQuery<T> query)
> o sea que quien llama GetByQuery tiene que construir un ISimpleQuery<T>
> la interface
> ISimpleQuery<T>
> tiene GetQuery(ISession) o sea que quien construye un ISimpleQuery<T>
> tiene que tener una referencia a NH
>
> Eso es cuando el explorador está tirando de la banana y ya le apareció
> el casco de bananas, sigue tirando y le aparece una cosa peluda... y
> se da cuenta que es la mano del mono que está encima de la rama...
>
>
> El 14 de mayo de 2009 15:54, "José F. Romaniello"
> <jfroma...@gmail.com <mailto:jfroma...@gmail.com>> escribió:
> <mailto:jfroma...@gmail.com <mailto:jfroma...@gmail.com>>>
> > <mailto:fabio...@gmail.com <mailto:fabio...@gmail.com>>>:

Fabio Maulo

unread,
May 14, 2009, 3:28:58 PM5/14/09
to altnet-a...@googlegroups.com
Decime solo si el GetQuery está en ISimpleQuery, si está allí ya tenes todo soldato.
Intenta sacar las interfaces en un assembly separado de las implementaciones, si podes hacerlo sin tener referencia a NH en los assemblies donde están las interfaces listo... si no podes hacerlo significa que está todo soldato.

Podes sostituir una implementación de ISimpleQuery para que trabaje con ADO puro ?
Podes sostituir una implementación de ISimpleQuery con algo cuyo datos vienen de un servicio externo al sistema ?

estas son casi questiones de gustos... casi... porque no entiendo a que sirve IoC y separación en capas logicas si las interfaces están atadas a una infraestructura especifica.
--
Fabio Maulo

"José F. Romaniello"

unread,
May 14, 2009, 3:50:55 PM5/14/09
to altnet-a...@googlegroups.com
Bueno si, entiendo para donde llegar... Para ISimpleQuery lo que podría
hacer es que el GetQuery reciba un IQueryable.. Después de todo hacer
siempre esto tampoco esta bueno:

public IQueryable<T> GetQuery(ISession session)
{
IQueryable<T> result = session.Linq<T>();

En ese caso si el día de mañana cambia la forma de obtener ese queryable
en mi repositorio o quiero usar un repositorio basado en ado puro..
mientras me de un queryable.

El problemas son las otras que están bastante mas atadas al ORM. En vez
de pasarle el Session le podría meter un Criteria... Pero estoy en la
misma y ya me estas haciendo dudar..
Decí que es un algo nuevo, tengo 3 queries y ninguna compleja.
Maldición, esta todo soldato y ni si quiera se que es eso.



Fabio Maulo escribió:
> Decime solo si el GetQuery está en ISimpleQuery, si está allí ya tenes
> todo soldato.
> Intenta sacar las interfaces en un assembly separado de las
> implementaciones, si podes hacerlo sin tener referencia a NH en los
> assemblies donde están las interfaces listo... si no podes hacerlo
> significa que está todo soldato.
>
> Podes sostituir una implementación de ISimpleQuery para que trabaje
> con ADO puro ?
> Podes sostituir una implementación de ISimpleQuery con algo cuyo datos
> vienen de un servicio externo al sistema ?
>
> estas son casi questiones de gustos... casi... porque no entiendo a
> que sirve IoC y separación en capas logicas si las interfaces están
> atadas a una infraestructura especifica.
>
> El 14 de mayo de 2009 16:17, "José F. Romaniello"
> <jfroma...@gmail.com <mailto:jfroma...@gmail.com>> escribió:

Fabio Maulo

unread,
May 14, 2009, 4:07:56 PM5/14/09
to altnet-a...@googlegroups.com
ves... ese es el tema....
"lo que podría", "día de mañana"
ya empezaste a usar el condiccional a futuro lo cual denota que hoy tenes todo soldado (de soldadura).
--
Fabio Maulo

Daniel Cazzulino

unread,
May 14, 2009, 6:23:10 PM5/14/09
to altnet-a...@googlegroups.com
IQueryable<T> es el futuro.
La composabilidad de querying q te da es muy poderosa, y permite todas las cosas bonitas q senialo el amigo Fabio.

Asi q por mi parte voy a ignorar el problema hasta q sea irrelevante (i.e. todo el mundo provea implementaciones de LINQ providers completas) :-P


/kzu

PD: Casi lo mismo q hice con Moq cuando decian q era un problema q no soportara VB porq VB no se q carancho de lambdas/funcs no soporta y no se q corcho. Ahora con VS2010 arreglaron todo en VB y Moq va a andar sin tocar nada :))


--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/14 Fabio Maulo <fabio...@gmail.com>

Fabio Maulo

unread,
May 15, 2009, 12:15:22 AM5/15/09
to altnet-a...@googlegroups.com
El 14 de mayo de 2009 19:23, Daniel Cazzulino <kzu.net@gmail.com> escribió:
IQueryable<T> es el futuro. 

ok pero.... ya sabes... lo sistemas nos los piden para ayer 
--
Fabio Maulo

Rodolfo Finochietti

unread,
May 15, 2009, 9:26:56 AM5/15/09
to altnet-a...@googlegroups.com

Como dijo un poeta de La Plata “el futuro llego hace rato”, en nuestro caso varias veces y con distintos nombres: COM+, MFC, XSLT, Remoting, Web Services, etc. solo por nombrar algunos J

 

Yo no sería tan extremista en decir que IQueryable es el futuro (que de hecho no creo que lo sea, ya que la expansión de LINQ providers es, y va seguir siendo, muuuuy lenta), es solo un herramienta más que hay que usar adecuadamente y en el marco de un buen diseño. En ese sentido sigo sin ver cómo me puede ayudar a tener un diseño más cohesivo.

 

Además no puedo ignorar el problema hasta que sea irrelevante, desgraciadamente necesito trabajar hoy (y ayer).

 

PD: Estuve leyendo el artículo que mando Mauricio (http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx), es muy aleccionador…

 

From: altnet-a...@googlegroups.com [mailto:altnet-a...@googlegroups.com] On Behalf Of Daniel Cazzulino
Sent: jueves, 14 de mayo de 2009 19:23
To: altnet-a...@googlegroups.com
Subject: [altnet-argentina] Re: Dao, Repository y clases Query

 

IQueryable<T> es el futuro.

No virus found in this incoming message.
Checked by AVG - www.avg.com

Version: 8.5.329 / Virus Database: 270.12.31/2116 - Release Date: 05/15/09 06:16:00

Daniel Cazzulino

unread,
May 15, 2009, 12:57:51 PM5/15/09
to altnet-a...@googlegroups.com
entonces no voy a hacer mas sistemas para clientes hasta dentro de un tiempo :P

/kzu


--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


2009/5/15 Fabio Maulo <fabio...@gmail.com>

Daniel Cazzulino

unread,
May 15, 2009, 12:58:55 PM5/15/09
to altnet-a...@googlegroups.com
hay q dedicarse a hacer frameworks por un tiempo y no hacer aplicaciones, jajaja....


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


Fabio Maulo

unread,
May 15, 2009, 8:40:05 PM5/15/09
to altnet-a...@googlegroups.com
El 15 de mayo de 2009 13:58, Daniel Cazzulino <kzu.net@gmail.com> escribió:
hay q dedicarse a hacer frameworks por un tiempo y no hacer aplicaciones, jajaja....

No te rrias porque el camino es ese....

--
Fabio Maulo

Angel Java Lopez

unread,
May 15, 2009, 8:50:52 PM5/15/09
to altnet-a...@googlegroups.com
Hay que hacer aplicaciones que creen aplicaciones.... ;-)
 
Angel "Java" Lopez


 
2009/5/15 Fabio Maulo <fabio...@gmail.com>

Ariel Alegre

unread,
May 15, 2009, 8:52:18 PM5/15/09
to altnet-a...@googlegroups.com
quiero un sistema de ventas [enter]
 
¿para cuándo?
 
Saludos cordiales
 
Ing. Ariel Alegre
15-6252-2480 / 4383-2670
msn arieljo...@hotmail.com
----- Original Message -----
Sent: Friday, May 15, 2009 9:50 PM
Subject: [altnet-argentina] Re: Dao, Repository y clases Query

Angel Java Lopez

unread,
May 15, 2009, 8:56:28 PM5/15/09
to altnet-a...@googlegroups.com
Ah!
 
Vos no viniste a mis ultimas charlas.... ;-)
 
Ni estas leyendo lo que escribi hoy en Twitter... ;-)
Reply all
Reply to author
Forward
0 new messages