<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7116292436030406158</id><updated>2011-11-27T15:23:35.000-08:00</updated><category term='NHibernate'/><category term='Win7'/><category term='ASP.NET MVC 2'/><category term='NH3.0'/><category term='NStore'/><title type='text'>www.restimartinez.es</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-4241349610868522076</id><published>2010-11-12T05:40:00.000-08:00</published><updated>2010-11-12T05:40:30.682-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>Updating a persistent object transparently</title><content type='html'>En NHibernate, un objeto devuelto medianta búsqueda por identificador, como por ejemplo el método session.Get&amp;lt;T&amp;gt;(int id) o por cualquier otra consulta realizada a través de NHibernate, se asocia al contexto de la session y es lo que llamamos primera cache de NHibernate, first-level cache o session-level cache. En definitiva, una instancia persistente siempre se asocia a una session de NHibernate y tiene un comportamiento transaccional.&lt;br /&gt;&lt;pre class="brush: csharp; highlight: [7]"&gt;using (ISession s = factory.OpenSession())&lt;br /&gt;using (s.BeginTransaction())&lt;br /&gt;{&lt;br /&gt;   var user = s.CreateQuery("from User")&lt;br /&gt;               .SetMaxResults(1)&lt;br /&gt;               .UniqueResult&amp;lt;User&amp;gt;();&lt;br /&gt;   s.Get&amp;lt;User&amp;gt;(user.Id); //query no executed. Instance object exists in session&lt;br /&gt;   s.Transaction.Commit();         &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Dichas instancias participan en las transacciones y su estado se mantiene sincronizado al final de la transacción, pero también podría ocurrir antes, ya que se puede dar el caso de que NHibernate tenga la necesidad de sincronizar antes de ejecutar una consulta.&lt;br /&gt;Desde luego, NHibernate no modifica todas las filas que tiene almacenadas en ISession al finalizar cada transacción, esto sería una burrada; sino que sólo lo hace de aquellas que detecta que han cambiado. A este mecanismo se le conoce como "automatic dirty checking". Un objeto que ha sido modificado y aun no se ha sincronizado con la base de datos se le considera "dirty".&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;&lt;br /&gt;using (ISession s = factory.OpenSession())&lt;br /&gt;using (s.BeginTransaction())&lt;br /&gt;{&lt;br /&gt;    var users = s.CreateQuery("from User")&lt;br /&gt;                    .SetMaxResults(2)&lt;br /&gt;                    .List&amp;lt;User&amp;gt;();&lt;br /&gt;&lt;br /&gt;    User userNoUpdated = users[0];&lt;br /&gt;    User userUpdated = users[1];&lt;br /&gt;    userUpdated.Name = "name-updated";&lt;br /&gt;                    &lt;br /&gt;    s.Transaction.Commit();&lt;br /&gt;}&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Este ejemplo genera las siguientes SQL&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__AniQ-tQvNI/TNUl7F-GgEI/AAAAAAAAADo/_l_FTdG2E74/s1600/user-updated-sql.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/__AniQ-tQvNI/TNUl7F-GgEI/AAAAAAAAADo/_l_FTdG2E74/s1600/user-updated-sql.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Observamos varias cosas:&lt;br /&gt;&lt;br /&gt;1. &lt;u&gt;Sólo se modifica el objeto que ha cambiado&lt;/u&gt;&lt;br /&gt;En el ejemplo, se obtiene de base de datos dos objetos que almacena en la session, pero sólo se modifica uno por lo que NH lo marca como "dirty" para sincronizarlo al final de la transacción.&lt;br /&gt;&lt;br /&gt;2. &lt;u&gt;NHibernate hace un update de todas las columnas&lt;/u&gt;&lt;br /&gt;NHibernate es consciente de las columnas que se han modificado y se puede configurar (mediante el uso de dynamic-update="true" en los ficheros de mapeo) para que genere los "update" teniendo en cuenta esas columnas, pero la mejora es tan insignificante que no merece la pena usar, ya que cada vez que tenga que modificar ese objeto va a tener que generar esa sentencia para ese caso particular. Esto es muy costoso comparándolo con la alternativa por defecto, donde se ejecuta el "update" con todas las columnas;  en este caso, al inicializar la aplicación, NHibernate genera y cachea la sentencia "update" y, simplemente, se dedica a usarla cada vez que quiera guardar el objeto.&lt;br /&gt;&lt;br /&gt;3. &lt;u&gt;&lt;strong&gt;La modificación del objeto en base de datos es transparente para el desarrollador&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;Para modificar el objeto (y con esto me refiero a hacer un "update" en base de datos) no he tenido que llamar a "session.Update();". Para mí, esta funcionalidad es de las más importante que tiene NHibernate. Como he dicho anteriormente, NHibernate es conciente de los objetos que tiene en su session y está atento de los cambios que se producen en ellos. Aquel objeto fuera de su ámbito de session (detached object) no lo monitoriza para observar si cambia o no, y es en este caso especifico, donde se le puede dar uso al "session.Update();". Aquí tenéis un &lt;a href="http://nhforge.org/doc/nh/en/index.html#manipulatingdata-updating-detached"&gt;enlace a la referencia de NH&lt;/a&gt;. En general, es raro hacer uso del "session.Update()" en patrones "session-per-request", ya que lo normal es recuperar el objeto mediante el "session.Get&amp;lt;T&amp;gt;()" y luego, una vez en la session, trabajar con el.&lt;br /&gt;&lt;br /&gt;En definitiva, el hecho de obtener los objetos usando la session de NHiberate nos &lt;b&gt;abstrae de la base de datos&lt;/b&gt; y provoca un efecto en el cual &lt;b&gt;podemos trabajar con colecciones de objetos del dominio como si estuvieran en memoria&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;¿No os suena está frase? Pues es una definición prácticamente calcada del patrón &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;Repository&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-4241349610868522076?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/4241349610868522076/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=4241349610868522076' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/4241349610868522076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/4241349610868522076'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/11/updating-persistent-object.html' title='Updating a persistent object transparently'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__AniQ-tQvNI/TNUl7F-GgEI/AAAAAAAAADo/_l_FTdG2E74/s72-c/user-updated-sql.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-9099391679621077676</id><published>2010-11-06T02:08:00.000-07:00</published><updated>2010-11-06T02:08:14.925-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>Batch size and StatelessSession in NHibernate</title><content type='html'>&lt;p&gt;Hoy vamos a comprobar dos cosas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://davybrion.com/blog/2008/10/batching-nhibernates-dm-statements/"&gt;Batching NHibernate’s DML Statements&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://davybrion.com/blog/2008/10/bulk-data-operations-with-nhibernates-stateless-sessions/"&gt;Bulk Data Operations With NHibernate’s Stateless Sessions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Nuestro dominio será el siguiente&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;&lt;br /&gt;    public class CrudTest&lt;br /&gt;    {&lt;br /&gt;        public virtual Guid Id { get; set; }&lt;br /&gt;        public virtual string Description { get; set; }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;El fichero de mapeo&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;hibernate-mapping xmlns=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;br /&gt;                   assembly=&amp;quot;NHibernateInfo.Console&amp;quot;&lt;br /&gt;                   namespace=&amp;quot;NHibernateInfo.Console.Domain&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;class name=&amp;quot;CrudTest&amp;quot; table=&amp;quot;CrudTest&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;id name=&amp;quot;Id&amp;quot; column=&amp;quot;Id&amp;quot; type=&amp;quot;guid&amp;quot; &amp;gt;&lt;br /&gt;      &amp;lt;generator class=&amp;quot;assigned&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/id&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;Description&amp;quot;&lt;br /&gt;              length=&amp;quot;200&amp;quot;&lt;br /&gt;              not-null=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;/class&amp;gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Test 1 : Insertamos 20mil objetos sin usar Batch size ni StatelessSession&lt;/strong&gt;&lt;pre class="brush: csharp;"&gt;&lt;br /&gt;                Configuration configuration = new Configuration().Configure("NHibernate.config");&lt;br /&gt;                ISessionFactory factory = configuration.BuildSessionFactory();&lt;br /&gt;                &lt;br /&gt;                Stopwatch time = Stopwatch.StartNew();&lt;br /&gt;&lt;br /&gt;                using (ISession s = factory.OpenSession())&lt;br /&gt;                using (s.BeginTransaction())&lt;br /&gt;                {&lt;br /&gt;                    foreach (var testObject in CreateTestObjects(20000))&lt;br /&gt;                        s.Save(testObject);&lt;br /&gt;                    &lt;br /&gt;                    s.Transaction.Commit();&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                System.Console.WriteLine("Elapsed {0} ms", time.ElapsedMilliseconds);&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Para crear los objetos hacemos uso del siguiente metodo&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;&lt;br /&gt;        private static IEnumerable CreateTestObjects(int count)&lt;br /&gt;        {&lt;br /&gt;            for (var i = 0; i &lt; count; i++)&lt;br /&gt;                yield return new CrudTest&lt;br /&gt;                                 {&lt;br /&gt;                                     Id = Guid.NewGuid(),&lt;br /&gt;                                     Description = Guid.NewGuid().ToString()&lt;br /&gt;                                 };&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;strong style="color:darkblue"&gt;Elapsed 2699 ms&lt;/strong&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;strong&gt;Test 2: Activamos el batch size&lt;/strong&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt;&amp;lt;property name="adonet.batch_size"&amp;gt;100&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;strong style="color:darkblue"&gt;Elapsed 1600 ms&lt;/strong&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;strong&gt;Test 3: Activamos el StatelessSession&lt;/strong&gt;&lt;pre class="brush: csharp; highlight: [6, 10]"&gt;&lt;br /&gt;                Configuration configuration = new Configuration().Configure("NHibernate.config");&lt;br /&gt;                ISessionFactory factory = configuration.BuildSessionFactory();&lt;br /&gt;                &lt;br /&gt;                Stopwatch time = Stopwatch.StartNew();&lt;br /&gt;&lt;br /&gt;                using (IStatelessSession s = factory.OpenStatelessSession())&lt;br /&gt;                using (s.BeginTransaction())&lt;br /&gt;                {&lt;br /&gt;                    foreach (var testObject in CreateTestObjects(20000))&lt;br /&gt;                        s.Insert(testObject);&lt;br /&gt;                    &lt;br /&gt;                    s.Transaction.Commit();&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                System.Console.WriteLine("Elapsed {0} ms", time.ElapsedMilliseconds);&lt;br /&gt;&lt;/pre&gt;&lt;strong style="color:darkblue"&gt;Elapsed 1191 ms&lt;/strong&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt; (resumidas de los posts de &lt;a href="http://davybrion.com/blog/about-me/"&gt;Davy Brion&lt;/a&gt; y de la &lt;a href="http://nhforge.org/doc/nh/en/index.html#batch"&gt;documentación de NH&lt;/a&gt;)&lt;p&gt;Hay que poner especial atención al usar la Session para inserciones masivas. Podemos tener problemas de 'OutOfMemoryException' ya que NHibernate cachea todas las instancias en la cache de nivel de session. Una solución propuesta por la &lt;a href="http://nhforge.org/doc/nh/en/index.html#batch-inserts"&gt;documentación de NHibernate&lt;/a&gt; es la de ir volcando y liberando memoria cada ciertos objetos creados, en función del parámetro que le hayamos puesto al parámetro ADO batch size.&lt;/p&gt;&lt;p&gt;Asignar un valor adecuado al parámetro de configuración adonet.batch_size. El razonable deberá estar entre 10 y 50 (el 100 del ejemplo está puesto a modo didáctico).&lt;/p&gt;&lt;p&gt;Con la activación del batch_size a 100 conseguimos agrupar las sentencias de 100 en 100. Esto permite reducir los accesos a base de datos de 20.000 a 200, lo que se traduce en una mejora en cuanto al rendimiento. &lt;/p&gt;&lt;p&gt;Esto solo aplica a sentencias "insert", "update" y "delete", siempre y cuando los &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/03/20/nhibernate-poid-generators-revealed.aspx"&gt;generadores de identidad&lt;/a&gt; no sean de tipo post-insercion. Si usamos generadores de ese tipo, NH necesitará acceder a la base de datos para recuperar el identificador, por lo que esta agrupación no aplicaría para los "insert"; aunque sí sería válido para los "update" y "delete". En la documentación dicen lo siguiente "&lt;i&gt;Note that NHibernate disables insert batching at the ADO level transparently if you use an identiy identifier generator&lt;/i&gt;"&lt;/p&gt;&lt;p&gt;Si deseamos agrupar varias querys en una sola llamada a base de datos, podemos usar el &lt;a href="http://davybrion.com/blog/2008/06/the-query-batcher/"&gt;soporte MultiQuery de NHibernate&lt;/a&gt;, que sirvió de base para las &lt;a href="http://ayende.com/Blog/archive/2009/04/27/nhibernate-futures.aspx"&gt;características de Future&amp;lt;T&amp;gt; y FutureValue&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Por último, si nos piden que hagamos operaciones de insercción masiva partiendo de un modelo que ya tenemos implementado (infrastructura, mapping file, etc) habría que planterse la opción de hacerlo con IStatelessSession. El hecho de no usar la session de NHibernate provoca que el proceso gestione menos memoria (ya que no almacena valores en la cache de primer nivel ni lanza los eventos asociados) y es una opción bastante considerable a tener en cuenta.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-9099391679621077676?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/9099391679621077676/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=9099391679621077676' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/9099391679621077676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/9099391679621077676'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/11/batch-size-and-statelesssession-in.html' title='Batch size and StatelessSession in NHibernate'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-8527110618636219475</id><published>2010-11-03T03:58:00.000-07:00</published><updated>2010-11-03T03:58:54.079-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC 2'/><title type='text'>Viewing SQL generated using NHibernate Interceptor</title><content type='html'>Existe una forma muy cómoda de poder visualizar las consultas que realiza NHibernate mediante el uso de un profiler llamado &lt;a href="http://nhprof.com/"&gt;NHProf&lt;/a&gt;. Este profiler, implementado por un "crack" llamado &lt;a href="http://www.ayende.com/about-me.aspx"&gt;Ayende Rahien&lt;/a&gt;, tiene el único inconveniente de que una sola licencia cuesta 200€; y para un particular eso es bastante dinero.&lt;br /&gt;&lt;br /&gt;Si todavía no has conseguido que tu empresa te compre la licencia, ahí va mi alternativa (como primera aproximación) mediante el uso de interceptores sobre-escribiendo el método OnPrepareStatement:&lt;script class="brush: csharp;" type="syntaxhighlighter"&gt;&lt;![CDATA[  public class ShowSQLInterceptor : EmptyInterceptor    {        public override SqlString OnPrepareStatement(SqlString sql)        {            System.Console.WriteLine(sql.ToString());            return base.OnPrepareStatement(sql);        }    }]]&gt;&lt;/script&gt;El único inconveniente es que las consultas no llevan los valores y las visualizaremos de la siguiente forma:&lt;script class="brush: sql;" type="syntaxhighlighter"&gt;&lt;![CDATA[insert into users(name, nif, age, login)values (?, ?, ?, ?)select user_.name as name0_from users user_ where user_.nif = ?]]&gt;&lt;/script&gt;Podremos usar esta forma de visualizar las consultas usando httpModules para visualizar que sentencias SQL se están ejecutando cuando cargamos una página. Podéis ver un ejemplo para ASP.NET con WebForm en &lt;a href="http://szahariev.blogspot.com/2010/01/nhibernate-display-executed-sql-at.html"&gt;este enlace&lt;/a&gt;, aunque tambien valdría en ASP.NET MVC&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-8527110618636219475?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/8527110618636219475/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=8527110618636219475' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/8527110618636219475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/8527110618636219475'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/11/viewing-sql-generated-using-nhibernate.html' title='Viewing SQL generated using NHibernate Interceptor'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-1158571979840751501</id><published>2010-11-02T04:05:00.000-07:00</published><updated>2010-11-02T04:05:12.275-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NH3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>NH 3.0 Lazy Load Properties</title><content type='html'>En enero de este año, Ayende nos sorprende con una nueva característica implementada en NH3.0 llamada &lt;a href="http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx"&gt;"Lazy Properties"&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Referente a esta característica existen los siguientes enlaces:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://216.121.112.228/browse/NH-429"&gt;[NH-429]&lt;/a&gt; - Lazy load columns&lt;/li&gt;&lt;li&gt;&lt;a href="http://216.121.112.228/browse/NH-2148"&gt;[NH-2148]&lt;/a&gt; - Not possible to call methods on Proxy for lazy-property&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;El objetivo consiste en no cargar aquella propiedad del objeto marcada como "lazy" mientras no sea necesario. Se me ocurre algún contexto donde puede ser útil, como por ejemplo, alguna propiedad que almacene una imagen o alguna que guarde textos muy grandes (comentarios, descripciones, etc).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para probarlo supongamos el siguiente fichero de mapeo donde establecemos la propiedad Name del User con el atributo lazy a true:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/__AniQ-tQvNI/TM2sE1iJ1OI/AAAAAAAAADg/s-hJs9EeSBQ/s1600/lazy-property-mapping.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/__AniQ-tQvNI/TM2sE1iJ1OI/AAAAAAAAADg/s-hJs9EeSBQ/s1600/lazy-property-mapping.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Con el siguiente ejemplo podremos comprobar como funciona esta nueva característica. Para ello realizo una consulta obteniendo el primer usuario que encuentre; en esta consulta se puede observar que no obtiene datos para la columna Name. Posteriormente se accede a la propiedad Name del objeto recuperado y es en este momento cuando necesita realizar una segunda consulta, puesto que en la primera no se había traído el dato.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/__AniQ-tQvNI/TM20dAalVjI/AAAAAAAAADk/g_WrNz_wq_E/s1600/property-lazy-load-nh3-feature.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/__AniQ-tQvNI/TM20dAalVjI/AAAAAAAAADk/g_WrNz_wq_E/s1600/property-lazy-load-nh3-feature.png" /&gt;&lt;/a&gt;&lt;/div&gt;Si no ves correctamente la imagen pulsa sobre ella o pulsa en &lt;a href="http://4.bp.blogspot.com/__AniQ-tQvNI/TM20dAalVjI/AAAAAAAAADk/g_WrNz_wq_E/s1600/property-lazy-load-nh3-feature.png"&gt;este enlace&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Posiblemente le daremos bastante uso a esta nueva mejora !!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-1158571979840751501?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/1158571979840751501/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=1158571979840751501' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/1158571979840751501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/1158571979840751501'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/11/nh-30-lazy-load-properties.html' title='NH 3.0 Lazy Load Properties'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/__AniQ-tQvNI/TM2sE1iJ1OI/AAAAAAAAADg/s-hJs9EeSBQ/s72-c/lazy-property-mapping.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-6089368726434827392</id><published>2010-10-31T09:24:00.000-07:00</published><updated>2010-10-31T09:24:18.209-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><title type='text'>Enable IntelliSense for NHibernate</title><content type='html'>Preparando una ejemplo para probar NHibernate 3.0 me he dado cuenta que no tenía habilitado el Intellisense (ni para los ficheros de mapeo ni para la propia configuración). Buscando en blogs me doy cuenta que la solución pasa por copiar los ficheros "nhibernate-mapping.xsd" y "nhibernate-configuration.xsd" a la carpeta correspondiente del Visual Studio. Incluso en la propia referencia de NH lo recomienda:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Tip: to enable IntelliSense for mapping and configuration files, copy the appropriate .xsd files to \Common7\Packages\schemas\xml if you are using Visual Studio .NET 2003, or to\Xml\Schemas for Visual Studio 2005. &lt;/blockquote&gt;&lt;br /&gt;Recuerdo leer a Fabio en uno de sus comentarios que él nunca suele hacer eso y repasando el fichero de releasenotes.txt de NH3 me doy cuenta que existe una mejora en la Build 3.0.0.Alpha3 (rev5226) llamada &lt;a href="http://216.121.112.228/browse/NH-2321"&gt;[NH-2321] - Recommended method for xml intellisense&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Aquí leo que actualmente la recomendación es la de incluir los ficheros de validación de esquemas como parte de la solución y efectivamente funciona. Así pues, click derecho sobre la solución, add y elegimos "Existing item...". Buscamos los dos ficheros xsd y los seleccionamos con lo que tendremos esto:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__AniQ-tQvNI/TM2XFKbAv1I/AAAAAAAAADY/VtPkhSxxnc8/s1600/existing-item-schemas.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/__AniQ-tQvNI/TM2XFKbAv1I/AAAAAAAAADY/VtPkhSxxnc8/s1600/existing-item-schemas.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Ahora ya tendremos activado el Intellisense&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/__AniQ-tQvNI/TM2XQp6WcaI/AAAAAAAAADc/RLD5c8kq2l4/s1600/validate-schema-intellisense-nhibernate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/__AniQ-tQvNI/TM2XQp6WcaI/AAAAAAAAADc/RLD5c8kq2l4/s1600/validate-schema-intellisense-nhibernate.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-6089368726434827392?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/6089368726434827392/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=6089368726434827392' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/6089368726434827392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/6089368726434827392'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/10/enable-intellisense-for-nhibernate.html' title='Enable IntelliSense for NHibernate'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__AniQ-tQvNI/TM2XFKbAv1I/AAAAAAAAADY/VtPkhSxxnc8/s72-c/existing-item-schemas.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-7927691083516415757</id><published>2010-10-21T15:10:00.000-07:00</published><updated>2010-10-31T08:41:45.722-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Win7'/><title type='text'>Activar Quick Launch Bar en Win7</title><content type='html'>Sé que está escrito en millones de sitios pero así no tengo que buscarlo mas.&lt;br /&gt;1. Click derecho en la barra de tareas y elegimos "New toolbar..."&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/__AniQ-tQvNI/TMC0V1jiU_I/AAAAAAAAADM/1oO7Ug_LZVA/s1600/new-toolbar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/__AniQ-tQvNI/TMC0V1jiU_I/AAAAAAAAADM/1oO7Ug_LZVA/s1600/new-toolbar.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;2. En el campo de texto escribimos&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;%SystemDrive%\Users\%username%\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/__AniQ-tQvNI/TMC5CCYB_1I/AAAAAAAAADQ/iiDmJdRpE-E/s1600/chose_a_folder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/__AniQ-tQvNI/TMC5CCYB_1I/AAAAAAAAADQ/iiDmJdRpE-E/s1600/chose_a_folder.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;3. La barra de inicio rápido aparecerá a la derecha de la barra de tareas,  para ubicarlo en el lugar deseado es necesario primero desbloquear la  barra de tareas desmarcando "Lock the taskbar" y desactivando que muestre el título y el texto.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/__AniQ-tQvNI/TMC6FwqxUUI/AAAAAAAAADU/k3IBBxQ6FE0/s1600/uncheck-show-title.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/__AniQ-tQvNI/TMC6FwqxUUI/AAAAAAAAADU/k3IBBxQ6FE0/s1600/uncheck-show-title.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-7927691083516415757?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/7927691083516415757/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=7927691083516415757' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/7927691083516415757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/7927691083516415757'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/10/activar-quick-launch-bar-en-win7.html' title='Activar Quick Launch Bar en Win7'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/__AniQ-tQvNI/TMC0V1jiU_I/AAAAAAAAADM/1oO7Ug_LZVA/s72-c/new-toolbar.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7116292436030406158.post-551274579253250774</id><published>2010-06-04T02:42:00.000-07:00</published><updated>2010-06-04T02:42:38.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NStore'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC 2'/><title type='text'>NStore: Otra tienda virtual web</title><content type='html'>He tenido problemas donde tenía alojado mi blog, ya que por error eliminé el directorio donde estaba la estructura física del &lt;a href="http://wordpress.org/"&gt;wordpress&lt;/a&gt;, por lo que vuelvo a activar este a ver si por fin me animo a escribir mas.&lt;br /&gt;&lt;br /&gt;He creado un proyecto en codeplex llamado NStore (&lt;a href="http://nstore.codeplex.com"&gt;http://nstore.codeplex.com&lt;/a&gt;) donde trataré de crear una tienda virtual web hecha integramente en ASP.NET MVC 2. El objetivo consistirá en familiarizarse con esta nueva tecnología, así que no me critiquéis por no tener ideas originales, al fin y al cabo hoy en día está casi todo inventado.&lt;br /&gt;&lt;br /&gt;De momento solamente tengo implementados dos o tres "user stories":&lt;br /&gt;1. As I [anonymous user] I want [register] So that [log in in the system]&lt;br /&gt;2. As I [admin user authenticated] I want [management product] So that [show a list of products]&lt;br /&gt;3. As I [user authenticated] I want [view a list of product] So that [buy a product]&lt;br /&gt;&lt;br /&gt;En un futuro la idea es integrarlo con herramientas de pago:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Usar &lt;a href="http://www.codeproject.com/KB/aspnet/paypal_c_aspnet.aspx"&gt;Paypal&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Usar &lt;a href="http://www.authorize.net/"&gt;Authorize.NET&lt;/a&gt; basado en Payment Gateway&lt;/li&gt;&lt;li&gt;Usar servicios de tipo &lt;a href="https://www.swreg.org/"&gt;SWREG&lt;/a&gt; donde la gestión del pago queda fuera del dominio de la aplicación.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Habrá que estudiar las tres opciones y elegir alguna de ellas en función del criterio que nos impongamos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7116292436030406158-551274579253250774?l=restimartinez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://restimartinez.blogspot.com/feeds/551274579253250774/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7116292436030406158&amp;postID=551274579253250774' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/551274579253250774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7116292436030406158/posts/default/551274579253250774'/><link rel='alternate' type='text/html' href='http://restimartinez.blogspot.com/2010/06/nstore-otra-tienda-virtual-web.html' title='NStore: Otra tienda virtual web'/><author><name>Resti Martínez Risque</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/__AniQ-tQvNI/Rdmo4a-hcqI/AAAAAAAAAAY/SkL8UB0Xefc/s320/resti_architect.jpg'/></author><thr:total>0</thr:total></entry></feed>
