bueno... si eso significa "un solo paso" y eso eso lo que te gusta seguí los links que mandó Angel (AJL) ya que son para trabajar con StoredProcedures.
En este foro, es probable, que vas a encontrar poca ayuda sobre como trabajar con NH+SP exactamente porque quien trabaja con ORM trata de evitar meter logica de negocio en las SPs. Te hago otras preguntas: Como estas probando que esas SPs hacen exactamente lo que tienen que hacer ? Tenes un programa o algo "computerizado" que pruebe que cada SP se "porte bien" ? Si te piden de cambiar RDBMS contestá "no se puede", te pegas un tiro, o le facturas un fangote ? Cuanto programadores C# tenes y cuanto programadores de SPs tenes ? Cuanto te sale un programador C# y cuanto te sale un programador de SPs ? Que seguridad te da una SP que no te de un metodo de una clase ? Es mas rapido escribir una SP o uno o n metodos de clases C# ? Si mucha logica de negocio se ejecuta en la misma PC donde está el DB, cuanto escalable es tu applicación ? Cuanto cuesta agregar potencia de procesamiento a un server-DB y cuanto cuesta agregar un WEB-server ? Tengo otras, pero con estas creo que tenes para pensar un rato. El 21 de enero de 2010 11:51, Edgar Ramos <[email protected]> escribió: > Gracias a todos, se lee la ciencia, incribirme en este foro ha sido lo > mejor que hecho > > Bueno vamos por partes > > Fabio, de un solo paso, en resumen, mando a mi store procedure los > parametros necesarios y este internamente manejando transacciones, > actualiza, elimina, inserta en fin hace varias cosas, un ejemplo > seria, trabajo en un hotel , el cliente hace check-out, cancelo su > folio (cuenta), actualizo el estado del huesped a "huesped salio", > actualizo el estado de la habitacion a "habitacion sucia", en fin > varias cosas realacionadas en un solo store procedure > > Carlos y Jose, mil gracias por compartir sus conocimientos, si > efectivamente soy nuevo, pero que eso no les detenga, quiero ser bueno > asi que tengo que aprender de los buenos, si hay que leer, investigar, > lo hago con mucha ganas, durante mi vida he desarrollado software de > forma estructurada, el paso a POO, me ha costado pero sigo en la > lucha, pero no desmayo > > al leer sus posts, tengo la pauta de ir a consultar en internet mas > sobre estos temas, por ejemplo DDD, DomainEvent, patrones de diseño, > GRASP, etc > > gracias nuevamente > > > > El día 21 de enero de 2010 06:23, José F. Romaniello > <[email protected]> escribió: > > Si, ahora me di cuenta y tenes razón. Perdón si parece abrumadora la otra > > explicación > > > > El 21 de enero de 2010 07:54, Carlos Peix <[email protected]> > escribió: > >> > >> Hola Jose, > >> Estoy de acuerdo con vos, solo me gustaria que releas el primer post de > >> Edgar. > >> Puedo equivocarme pero entendi que el recien esta empezando con este > tipo > >> de diseño y juzgue que proponer un patron visitor lo asustaria o le > haria > >> mas dificil un primer paso. Mucho menos se me ocurriria apuntarlo al > blog de > >> Udi (con el cual estoy de acuerdo, sobre todo con DomainEvents). > >> Entiendo que para la mayoria de la audiencia de esta lista mi propuesta > >> parece juego de niños pero vale la pena, ya veran cuando dentro de un > par de > >> años Edgar nos solucione los problemas a nosotros o a otros :-). > >> De todas maneras esta bueno que tenga alternativas para elegir. > >> Un abrazo > >> ---------------------------------- > >> Carlos Peix > >> > >> 2010/1/21 José F. Romaniello <[email protected]> > >>> > >>> No me gusta esta arquitectura Carlos. > >>> Para mi el servicio que lleva a cabo el caso de uso de dar de alta una > >>> venta tiene que terminar grabando una venta con su repositorio. Tal vez > el > >>> movimiento de stock, es un agregado de la misma venta, pero para este > caso > >>> voy a suponer que no. > >>> Hace un tiempo escribí sobre un dominio "parecido" ;) > >>> > >>> > http://jfromaniello.blogspot.com/2009/11/caso-practico-patron-visitor.html > >>> > >>> Mi idea es que e > >>> public class RegistroDeVentas > >>> { > >>> IVisitor<Venta> visitors; > >>> public RegistroDeVentas(IVisitor<Venta>...visitors, > IRepositorioVenta > >>> repVenta) { > >>> } > >>> public RegistrarVenta(Venta venta) > >>> { > >>> foreach (var visitor in visitors) > >>> { > >>> if(visitor.EsAplicable(venta)) > >>> visitor.Aplicar(venta) > >>> } > >>> repVenta.Guardar(venta) > >>> } > >>> } > >>> La interfaz IVisitor tiene solo esos dos metodos que aparecen ahí, en > la > >>> configuración del container digo que visitors se aplican para este use > >>> case. > >>> Un ejemplo de visitor para Movimiento Stock sería > >>> public class AplicadorDeStockPorVentas : IVisitor<Venta> > >>> { > >>> public AplicadorDeStockPorVentas(IRepositorioStock repStock){ > >>> repStock = ...} > >>> public bool EsAplicable(Venta venta) > >>> { > >>> return venta.TipoDeVenta.MueveStockFisico && > >>> venta.EntregaInmediata > >>> } > >>> public void Aplicar(Venta venta) > >>> { > >>> foreach(var linea in venta.Lineas) > >>> { > >>> var movStock = new MovimientoStock(linea.Articulo, > >>> linea.Cantidad, Signo.Debito); > >>> repStock.Guardar(movStock); > >>> } > >>> } > >>> } > >>> Me encanta este tipo de código por que es muy facil testearlo. > >>> Si bien en su momento estaba convencido ahora me copa mas la idea de > >>> DomainEvents, igual, el código me queda muy similar. > >>> Yo uso la misma implementación de Udi, solamente que con > ServiceLocator, > >>> y en vez de ser todo estática la clase DomainEvents, tengo un > IDomainEvents > >>> (o IDomainEventsManager el cual inyecto en los servicios) > >>> http://www.udidahan.com/2009/06/14/domain-events-salvation/ > >>> > >>> El 21 de enero de 2010 00:13, Carlos Peix <[email protected]> > >>> escribió: > >>>> > >>>> Hola Edgard, > >>>> Creo que deberias mirar codigo escrito por otros para tener una vision > >>>> global. Aunque no adhiero 100% a los detalles de esta arquitectura, > podrias > >>>> mirar esto: http://code.google.com/p/sharp-architecture/ > >>>> No obstante, te dejo aqui algo esquematico (no me critiquen por favor, > >>>> abajo aclaro como profesionalizar este codigo :-) ). > >>>> Supongamos que tenes una clase que representa la venta: > >>>> public class Venta { > >>>> IList<LineaVenta> lineas; > >>>> } > >>>> y otra que representa a un movimiento de stock > >>>> public class MovimientoStock { > >>>> IList<LineaMovimientoStock> lineas; > >>>> } > >>>> Luego se me ocurre una suerte de servicio o de componente cuya > >>>> responsabilidad sea aplicar la venta contra el stock: > >>>> public class AplicadorDeVentaAStock { > >>>> public MovimientoStock AplicarVenta(Venta venta) { > >>>> // aqui va la logica por la cual se aplica la venta y se CREA > >>>> // un objeto MovimientoStock > >>>> return movimientoStock; > >>>> } > >>>> } > >>>> Como veras, hasta aqui no hay nada de persistencia, solo logica de > >>>> negocio. > >>>> Veamos ahora como interviene la persistencia: seguramente un usuario > >>>> presionara un boton cuando quiere grabar la venta, en el codigo de ese > boton > >>>> deberia llamarse a un objeto (un servicio o fachada de aplicacion) > cuya > >>>> responsabilidad sea registrar la venta: > >>>> public class RegistroDeVentas { > >>>> public void Registrar(Venta venta) { > >>>> MovimientoStock movimientoStock > >>>> = aplicadorDeVentaAStock.AplicarVenta(venta); > >>>> repositorioVenta.Save(venta); > >>>> repositorioMovimientoStock.Save(movimientoStock); > >>>> } > >>>> } > >>>> Es sencillo no? la version real no tiene que ser mas compleja pero > creo > >>>> que es necesario dar algunas pautas y aclaraciones. > >>>> De donde salen aplicadorDeVentaAStock, repositorioVenta > >>>> y repositorioMovimientoStock en el metodo Registrar? es aqui donde > aparece > >>>> injeccion de dependencias o DI, no voy a configurar todo eso pero si > voy a > >>>> sugerir el contructor de la clase RegistroDeVentas: > >>>> public class RegistroDeVentas { > >>>> IAplicadorDeVentaAStock aplicadorDeVentaAStock; > >>>> IRepositorioVenta repositorioVenta; > >>>> IRepositorioMovimientoStock repositorioVenta; > >>>> > >>>> > public RegistroDeVentas(IAplicadorDeVentaAStock aplicadorDeVentaAStock, > >>>> IRepositorioVenta > >>>> repositorioVenta, > >>>> > >>>> IRepositorioMovimientoStock repositorioVenta) { > >>>> this.aplicadorDeVentaAStock = aplicadorDeVentaAStock; > >>>> this.repositorioVenta = repositorioVenta; > >>>> this.repositorioMovimientoStock = repositorioMovimientoStock; > >>>> } > >>>> } > >>>> Estas instancias seran "injectadas" en esta fachada de servicio por un > >>>> container, por ejemplo, Windsor. > >>>> Alguno que todavia este despierto notara que use el > >>>> tipo IAplicadorDeVentaAStock para el aplicador de stock, esto nos > permitira, > >>>> dependiendo de las preferencias de nuestro cliente, utilizar distintas > >>>> estrategias de aplicacion de stock. Esto es el patron Strategy. > >>>> Por supuesto que tambien debe iniciarse transacciones asociadas a los > >>>> repositorios, tambien puede hacerse mediante configuracion. > >>>> Creo que con este esquemas tenes algo sencillo que puede servir para > >>>> aclararte el panorama al tiempo que, con las aclaraciones que agregue > mas un > >>>> poco de investigacion de tu parte llegar a algo bastante profecional, > >>>> extensible y testeable. > >>>> Un saludo. > >>>> PD: Pierde Boca, gana River :-( > >>>> ---------------------------------- > >>>> Carlos Peix > >>>> > >>>> 2010/1/20 Edgar Ramos <[email protected]> > >>>>> > >>>>> Gracias por los comentarios, antes manejaba toda esta logica con > store > >>>>> procedures y triggers, hoy requiero hacerlo de la forma correcta, > >>>>> Carlos tu punto de vista me ha quedado gustando, algun link donde > >>>>> profundizar seria bienvenido > >>>>> > >>>>> > >>>>> saludos > >>>>> > >>>>> El día 20 de enero de 2010 15:46, Carlos Peix <[email protected] > > > >>>>> escribió: > >>>>> > Diego, > >>>>> > Para que veas que soy un caballero: yo no disiento con vos. :-) > >>>>> > Por supuesto que Diego tiene razon pero, conceptualmente, lo que > >>>>> > señala es > >>>>> > el equivalente a un store procedure (mas precisamente un trigger) > >>>>> > escrito en > >>>>> > C#. > >>>>> > Puede funcionar pero no es recomendable en un diseño nuevo, desde > >>>>> > cero. Al > >>>>> > menos en mi opinion. > >>>>> > ---------------------------------- > >>>>> > Carlos Peix > >>>>> > > >>>>> > 2010/1/20 Diego Mijelshon <[email protected]> > >>>>> >> > >>>>> >> Disiento con Carlos respecto de si es _posible_ hacer esto, aunque > >>>>> >> estoy > >>>>> >> de acuerdo en que no es un muy buen diseño. > >>>>> >> Para lograr algo así, podrías usar un PostInsertEventListener que > >>>>> >> haga la > >>>>> >> actualización. > >>>>> >> Algo más o menos así (no testeado): > >>>>> >> void OnPostInsert(PostInsertEvent @event) > >>>>> >> { > >>>>> >> var linea = @event.Entity as Linea; > >>>>> >> if (linea != null) > >>>>> >> @event.Session.CreateQuery("update Producto set Stock = Stock > - > >>>>> >> :cantidad where Id = :idProducto") > >>>>> >> .SetParameter("cantidad", linea.Cantidad) > >>>>> >> .SetParameter("idProducto", linea.Producto.Id) > >>>>> >> .ExecuteUpdate() > >>>>> >> } > >>>>> >> Así y todo, estarías usando un event listener, que es una > >>>>> >> herramienta de > >>>>> >> infraestructura de NHibernate para un concern específico de > negocio, > >>>>> >> lo cual > >>>>> >> tiene bastante mal olor. > >>>>> >> > >>>>> >> Diego > >>>>> >> > >>>>> >> > >>>>> >> 2010/1/20 Edgar Ramos <[email protected]> > >>>>> >>> > >>>>> >>> Saludos a todos > >>>>> >>> > >>>>> >>> Como ejemplo similar el siguiente > >>>>> >>> > >>>>> >>> Tengo estas entidades, Venta, Linea (detalle de la venta), y > >>>>> >>> Producto > >>>>> >>> (con su stock), y requiero hacer lo siguiente > >>>>> >>> > >>>>> >>> Al momento de crear Una venta e ingresar su Detalle (Linea), me > >>>>> >>> actualice el stock de cada uno de los productos (de Linea), > >>>>> >>> basicamente stock=stock-(cantidad digitada) > >>>>> >>> > >>>>> >>> Puedo hacer esto ? > >>>>> >>> > >>>>> >>> Cualquier comentario es bienvenido > >>>>> >>> > >>>>> >>> Gracias nuevamente > >>>>> >>> > >>>>> >>> -- > >>>>> >>> Para escribir al Grupo, hágalo a esta dirección: > >>>>> >>> [email protected] > >>>>> >>> Para más, visite: > http://groups.google.com/group/NHibernate-Hispano > >>>>> >> > >>>>> >> > >>>>> >> -- > >>>>> >> Para escribir al Grupo, hágalo a esta dirección: > >>>>> >> [email protected] > >>>>> >> Para más, visite: > http://groups.google.com/group/NHibernate-Hispano > >>>>> > > >>>>> > > >>>>> > -- > >>>>> > Para escribir al Grupo, hágalo a esta dirección: > >>>>> > [email protected] > >>>>> > Para más, visite: > http://groups.google.com/group/NHibernate-Hispano > >>>>> > > >>>>> > >>>>> -- > >>>>> Para escribir al Grupo, hágalo a esta dirección: > >>>>> [email protected] > >>>>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >>>> > >>>> > >>>> -- > >>>> Para escribir al Grupo, hágalo a esta dirección: > >>>> [email protected] > >>>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >>> > >>> > >>> -- > >>> Para escribir al Grupo, hágalo a esta dirección: > >>> [email protected] > >>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >> > >> > >> -- > >> Para escribir al Grupo, hágalo a esta dirección: > >> [email protected] > >> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > > > > > > -- > > Para escribir al Grupo, hágalo a esta dirección: > > [email protected] > > Para más, visite: http://groups.google.com/group/NHibernate-Hispano > > > > -- > Para escribir al Grupo, hágalo a esta dirección: > [email protected] > Para más, visite: http://groups.google.com/group/NHibernate-Hispano > -- Fabio Maulo
-- Para escribir al Grupo, hágalo a esta dirección: [email protected] Para más, visite: http://groups.google.com/group/NHibernate-Hispano
