<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">QuintaStation</title><subtitle type="html">Blog técnico de Eduardo Quintás sobre tecnologías Microsoft</subtitle><id>http://geeks.ms/blogs/quintas/atom.aspx</id><link rel="alternate" type="text/html" href="http://geeks.ms/blogs/quintas/default.aspx" /><link rel="self" type="application/atom+xml" href="http://geeks.ms/blogs/quintas/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2006-08-06T10:49:00Z</updated><entry><title>Entrevista en Comando Tomate</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/05/07/entrevista-en-comando-tomate.aspx" /><id>/blogs/quintas/archive/2008/05/07/entrevista-en-comando-tomate.aspx</id><published>2008-05-07T17:57:00Z</published><updated>2008-05-07T17:57:00Z</updated><content type="html">&lt;p&gt;Otra desternillante pero útil entrevista en comando tomate. Para los que no me conozcan cuento un poco lo que hago en la Universidad y para PlainConcepts. Además cuento alguna anédocta y consejos del &amp;quot;tomate&amp;quot; para los desarrolladores :)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;En breve publicaran otra entrevista más técnica sobre Spring.Net&lt;/p&gt;&lt;iframe src="http://silverlight.services.live.com/invoke/34206/eduardoquintas/iframe.html" frameborder="0" width="450" scrolling="no" height="350" mce_src="http://silverlight.services.live.com/invoke/34206/eduardoquintas/iframe.html"&gt;&lt;/iframe&gt;
&lt;p&gt;Originalmente publicada aquí: &lt;a href="http://comandotomate.net/archive/2008/05/07/entrevista-a-eduardo-quint-225-s.aspx"&gt;http://comandotomate.net/archive/2008/05/07/entrevista-a-eduardo-quint-225-s.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=85028" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="Comando Tomate" scheme="http://geeks.ms/blogs/quintas/archive/tags/Comando+Tomate/default.aspx" /></entry><entry><title>Evento .NUGG: IIS7.0 en A Coruña</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/05/07/evento-nugg-iis7-0.aspx" /><id>/blogs/quintas/archive/2008/05/07/evento-nugg-iis7-0.aspx</id><published>2008-05-07T17:45:00Z</published><updated>2008-05-07T17:45:00Z</updated><content type="html">&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;Tras colaborar en el Visual Studio 2008 Tour, el grupo .Nugg (.Net User Group Galicia) tiene nuevo evento:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;font face="Tahoma" size="2"&gt;&lt;strong&gt;IIS 7.0: Hágase la luz&lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;El &lt;strong&gt;16 de Mayo de 17:00 a 19:30, &lt;/strong&gt;Iván González, MVP de IIS, nos va a contar las novedades de Internet Information Services 7.0 en Windows Server 2008 y Windows Vista.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;El evento es, como todos los de .Nugg en A Coruña, en el edificio Xoana Capdevielle dentro del campus de Elviña (Universidade da Coruña).&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;Es necesario que os registreis.. que luego no hay sitio :p&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="eslabelnormal"&gt;&lt;a class="" href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032378922&amp;amp;Culture=es-ES" target="_blank"&gt;&lt;span style="COLOR:windowtext;"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032378922&amp;amp;Culture=es-ES&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="COLOR:#1f497d;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span class="eslabelnormal"&gt;&lt;span style="FONT-SIZE:11pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;font face="tahoma,arial,helvetica,sans-serif" size="2"&gt;Un mapita de cómo llegar, especialmente para la gente de fuera&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;iframe marginwidth="0" marginheight="0" src="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=es&amp;amp;msa=0&amp;amp;msid=112446040967221334224.00044475947d03a539b25&amp;amp;s=AARTsJrHhM8-F-o9_xLlQAEzkgMX2VO6Lg&amp;amp;ll=43.330422,-8.394241&amp;amp;spn=0.029968,0.054932&amp;amp;z=14&amp;amp;output=embed" frameborder="0" width="450" height="480"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;a style="COLOR:#0000ff;TEXT-ALIGN:left;" href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=es&amp;amp;msa=0&amp;amp;msid=112446040967221334224.00044475947d03a539b25&amp;amp;ll=43.330422,-8.394241&amp;amp;spn=0.029968,0.054932&amp;amp;z=14&amp;amp;source=embed"&gt;Ver mapa más grande&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=85027" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="Evento" scheme="http://geeks.ms/blogs/quintas/archive/tags/Evento/default.aspx" /><category term=".NUGG" scheme="http://geeks.ms/blogs/quintas/archive/tags/.NUGG/default.aspx" /><category term="MVP" scheme="http://geeks.ms/blogs/quintas/archive/tags/MVP/default.aspx" /><category term="IIS7.0" scheme="http://geeks.ms/blogs/quintas/archive/tags/IIS7.0/default.aspx" /><category term="Windows Server 2008" scheme="http://geeks.ms/blogs/quintas/archive/tags/Windows+Server+2008/default.aspx" /><category term="IIS" scheme="http://geeks.ms/blogs/quintas/archive/tags/IIS/default.aspx" /></entry><entry><title>nHibernate en Comando Tomate</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/04/30/nhibernate-en-comando-tomate.aspx" /><id>/blogs/quintas/archive/2008/04/30/nhibernate-en-comando-tomate.aspx</id><published>2008-04-30T16:52:00Z</published><updated>2008-04-30T16:52:00Z</updated><content type="html">&lt;p&gt;Os presento una entrevista que me hizo Elisa para el &lt;a class="" title="Comaaaando Tomaaaateeeee" href="http://comandotomate.net/"&gt;Comando Tomate&lt;/a&gt;, que es un espacio web&amp;nbsp;rojo con una misión tecnológicamente tomatera, verde y madura. Que además de entretener, educa :p&lt;br /&gt;Atentos a mi destreza en las manos... lo aprendí de los mejores políticos :p&amp;nbsp; Además hablo de &lt;strong&gt;nHibernate&lt;/strong&gt;. &lt;br /&gt;Mi frase favorita, de esas que le salen a uno porque se quiere a si mismo (jejeje) &lt;em&gt;: &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;quot;Yo conozco SQL y le (por nhibernate) he visto sacar consultas mucho mejor CASI de las que podría hacer yo&amp;quot;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Eduardo Quintás en Comando Tomate.&lt;/em&gt;&lt;/p&gt;&lt;iframe src="http://silverlight.services.live.com/invoke/34206/nhibernate/iframe.html" frameborder="0" width="525" scrolling="no" height="400" mce_src="http://silverlight.services.live.com/invoke/34206/nhibernate/iframe.html"&gt;&lt;/iframe&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=84587" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="nHibernate" scheme="http://geeks.ms/blogs/quintas/archive/tags/nHibernate/default.aspx" /><category term="Comando Tomate" scheme="http://geeks.ms/blogs/quintas/archive/tags/Comando+Tomate/default.aspx" /><category term="Acceso a Datos" scheme="http://geeks.ms/blogs/quintas/archive/tags/Acceso+a+Datos/default.aspx" /><category term="Capit&amp;#225;n Tomate" scheme="http://geeks.ms/blogs/quintas/archive/tags/Capit_26002300_225_3B00_n+Tomate/default.aspx" /><category term="Open Source" scheme="http://geeks.ms/blogs/quintas/archive/tags/Open+Source/default.aspx" /><category term="Arquitectura Empresarial" scheme="http://geeks.ms/blogs/quintas/archive/tags/Arquitectura+Empresarial/default.aspx" /><category term="ORM" scheme="http://geeks.ms/blogs/quintas/archive/tags/ORM/default.aspx" /></entry><entry><title>Materiales de la charla: ADO.NET 3.0 Entity Framework</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/03/04/materiales-de-la-charla-ado-net-3-0-entity-framework.aspx" /><id>/blogs/quintas/archive/2008/03/04/materiales-de-la-charla-ado-net-3-0-entity-framework.aspx</id><published>2008-03-04T12:57:00Z</published><updated>2008-03-04T12:57:00Z</updated><content type="html">&lt;p&gt;Tal como os había prometido a los que acudisteis a la charla os publico (un poco tarde, I know) los materiales de la misma.&lt;/p&gt;
&lt;p&gt;Tenéis aquí la presentación de &lt;a class="" href="http://geeks.ms/files/folders/quintas/entry76663.aspx"&gt;ADO.NET 3.0 Entity Framework Beta3&lt;/a&gt; (está en pptx, 337KB) y también el &lt;a class="" href="http://geeks.ms/files/folders/quintas/entry76666.aspx"&gt;código fuente&lt;/a&gt; de lo realizado en la charla (en zip 40KB).&lt;/p&gt;
&lt;p&gt;Para el código fuente es&amp;nbsp;necesaria la base de datos MyPeople.mdf que puede encontrase en el GettingStarted de EF BETA 3 en codeplex: &lt;br /&gt;&lt;a href="http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=adonetsamples&amp;amp;DownloadId=23191"&gt;http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=adonetsamples&amp;amp;DownloadId=23191&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=76661" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>ADO.NET Entity Framework: Reattaching detached objects in short Lived contexts</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/02/21/ado-net-entity-framework-attaching-detached-objects-in-short-lived-contexts.aspx" /><id>/blogs/quintas/archive/2008/02/21/ado-net-entity-framework-attaching-detached-objects-in-short-lived-contexts.aspx</id><published>2008-02-21T10:23:00Z</published><updated>2008-02-21T10:23:00Z</updated><content type="html">&lt;p&gt;Most enterprise applications uses an architectural pattern that needs a stateless facade for its business logic. So they can use it in several scenarios like WebServices or WCF, ASP.NET applications, Traditional Desktop Application (Windows Forms, WPF).. etc.&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re using Entinty Framework, your derived ObjectContext is called &lt;em&gt;short lived context&lt;/em&gt; and there is some issues about it. My last post (in spannish language) explores best practices for better perfomance with &lt;em&gt;short lived contexts &lt;/em&gt;in Entity Framework.&lt;/p&gt;
&lt;p&gt;In this post I speak about re-attach modified EntityObjects, that were updated outside of an ObjectContext (in detached state). This is a very common scenario when you&amp;#39;re using stateless facades.&lt;/p&gt;
&lt;p&gt;So, imagine that your facade retrieves an EntityObject of your model and passes it to some visual control in&amp;nbsp;the user interface. When an user or a process in IU changes your EntityObject, this object is in a detached state, so&amp;nbsp;there&amp;nbsp;isn&amp;#39;t an ObjectStateManager tracking changes. When your passes it again to the facade at your Business Logic Layer this object needs to be persisted. Problem is that the new ObjectContext doesn&amp;#39;t know about changes in&amp;nbsp;properties, so when&amp;nbsp;you call SaveChanges() nothing happens.&lt;/p&gt;
&lt;p&gt;At User Interface layer:&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;MyEntity entity = Facade.GetEntityById(1);&amp;nbsp;&lt;br /&gt;BindEntitiesToControls();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;(User interaction that changes values in the detached object, by example&amp;nbsp;a roundtrip&amp;nbsp;in an ASP.NET app. The entity object could be in the viewstate or HttpSession)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;entity.PropertyValue = 4;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(User clicks&amp;nbsp;&amp;quot;Save&amp;quot; button)&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;Facade.Save(entity);&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;At Business Layer Facade (naive aproximation):&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;public static void Save(EntityObject entity)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; using(MyContext ctx = new MyContext)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.Attach(entity);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.SaveChanges();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp; &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;This aprox. does&amp;nbsp;NOT work!!! because the ObjectContext unknowns the changes ocurred in entity object when it was detached.&lt;/p&gt;
&lt;p&gt;Upsss, but this is a very common scenario, so what can i do?&lt;/p&gt;
&lt;p&gt;Take a look to this extensor method for&amp;nbsp;an ObjectContext:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080" size="2"&gt;///&lt;/font&gt;&lt;font color="#008000" size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;&amp;lt;summary&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080" size="2"&gt;///&lt;/font&gt;&lt;font color="#008000" size="2"&gt; Attach an EntityObject that was modified when detached&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080" size="2"&gt;///&lt;/font&gt;&lt;font color="#008000" size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;&amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080" size="2"&gt;///&lt;/font&gt;&lt;font color="#008000" size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;&amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080" size="2"&gt;///&lt;/font&gt;&lt;font color="#008000" size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;&amp;lt;param name=&amp;quot;objectDetached&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;DetachedObject&lt;/font&gt;&lt;font color="#808080" size="2"&gt;&amp;lt;/param&amp;gt;&lt;/p&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;static&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; AttachUpdated(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;this&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;ObjectContext&lt;/font&gt;&lt;font size="2"&gt; obj, &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;EntityObject&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="courier new,courier"&gt; objectDetached)&lt;br /&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (objectDetached.EntityState == &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;EntityState&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="courier new,courier"&gt;.Detached)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="courier new,courier"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#0000ff" size="2"&gt;object&lt;/font&gt;&lt;font size="2"&gt; original = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="courier new,courier"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (obj.TryGetObjectByKey(objectDetached.EntityKey, &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;out&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="courier new,courier"&gt; original))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="courier new,courier"&gt;obj.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, &lt;/font&gt;&lt;font face="courier new,courier"&gt;objectDetached);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font face="courier new,courier"&gt;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#0000ff" size="2"&gt;throw&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;ObjectNotFoundException&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="courier new,courier"&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="courier new,courier"&gt;}&lt;br /&gt;&lt;/font&gt;&lt;font face="courier new,courier"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;&lt;/font&gt;This&amp;nbsp;extensor method first tries to load original&amp;nbsp;entity into the&amp;nbsp;object cache. If it&amp;#39;s already loaded, nothing happens; if not, it is retrieved from the storage.&lt;br /&gt;Then applies the objectDetached properties to the original object retrieved in last step.&lt;/p&gt;
&lt;p&gt;Our new facade method could be:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;public static void Save(EntityObject entity)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; using(MyContext ctx = new MyContext)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.AttachUpdated(entity);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.SaveChanges();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp; &lt;br /&gt;}&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=73188" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="ADO.Net" scheme="http://geeks.ms/blogs/quintas/archive/tags/ADO.Net/default.aspx" /><category term="Entity Framework" scheme="http://geeks.ms/blogs/quintas/archive/tags/Entity+Framework/default.aspx" /><category term="Short Lived Contexts" scheme="http://geeks.ms/blogs/quintas/archive/tags/Short+Lived+Contexts/default.aspx" /></entry><entry><title>ADO.NET Entity Framework: Buenas prácticas para contextos de tiempo de vida cortos</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/02/14/buenas-pr-225-cticas-para-contextos-de-tiempo-de-vida-cortos-en-ado-net-entity-framework-beta3.aspx" /><id>/blogs/quintas/archive/2008/02/14/buenas-pr-225-cticas-para-contextos-de-tiempo-de-vida-cortos-en-ado-net-entity-framework-beta3.aspx</id><published>2008-02-13T23:13:00Z</published><updated>2008-02-13T23:13:00Z</updated><content type="html">&lt;h1 style="MARGIN:24pt 0cm 0pt;"&gt;&lt;font face="Calibri" size="3"&gt;En este &lt;em&gt;post&lt;/em&gt; comento una serie &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;buenas prácticas para mejorar la eficiencia de ADO.NET Entity Framework (EF) en escenarios de aplicaciones empresariales dónde es recomendable utilizar contextos de tiempo de vida cortos (&lt;i style="mso-bidi-font-style:normal;"&gt;Short Lived Contexts&lt;/i&gt;)&lt;/font&gt;&lt;/h1&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;&lt;em&gt;AVISO: Lo aquí expuesto es aplicable a ADO.NET Entity Framework Beta 3. Es posible que en versiones posteriores esta información no sea correcta.&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="4"&gt;Introducción&lt;/font&gt;&lt;/h2&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Los principales patrones arquitectónicos para aplicaciones empresariales emplean una fachada que expone al UI o UIC la lógica de negocio de la misma. Esta fachada idealmente no debe mantener el estado (&lt;i style="mso-bidi-font-style:normal;"&gt;stateless) &lt;/i&gt;para que, entre otras razones, pueda utilizarse desde aplicaciones web como ASP.NET, servicios web,&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;WCF o clientes inteligentes ligeros en forma de aplicación de escritorio tradicional.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Si empleamos EF en nuestra capa de negocio tendremos métodos&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;que crean un ObjectContext local al inicio de su ejecución y liberan al final del método tras realizar una serie de operaciones de lógica de negocio mayormente breves. Se dice que estos ObjectContext son &lt;i style="mso-bidi-font-style:normal;"&gt;Short Lived &lt;/i&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;o de tiempo de vida corto.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Por el contrario, los contextos de tiempo de vida largo (&lt;i style="mso-bidi-font-style:normal;"&gt;long lived contexts)&lt;/i&gt;, suelen estar asociados a aplicaciones de escritorio o consola tradicionales y se crean y destruyen al inicio y fin de la aplicación. Si bien también se aplica cada vez más el patrón arquitectónico anteriormente descrito en estas aplicaciones empresariales de escritorio. Así es posible distribuir la lógica de negocio y que la aplicación empresarial&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;con interface de escritorio (WPF, WindowsForms, Consola…) se comporte como un cliente inteligente ligero. Además podríamos aprovechar dicha lógica de negocio para ser usada con aplicaciones con interfaz web o desde servicios web o incluso WCF.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Los ORMs (Object Relational Mapping) como Entity Framework o NHibernate se emplean principalmente en estos escenarios empresariales y es curioso que la mayoría de la literatura y documentación al respecto inciden en presentar sus características en entornos con contextos de tiempo de vida largo y apenas se encuentran referencia a los &lt;i style="mso-bidi-font-style:normal;"&gt;Short Lived Context&lt;/i&gt; cuando son prácticamente el escenario arquitectónico empresarial más común.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Una de las ventajas de los ORMs es que nos dan una indirección estupenda del almacén final de datos y su consulta específica. Pero también nos añade el desconocimiento de cómo trabaja internamente y si el código que escribimos es o no eficiente. Para crear aplicaciones empresariales eficientes, algo imprescindible en entornos empresariales con alto número de peticiones, es preciso conocer cómo trabaja internamente el ORM que empleamos y el Entity Framework no es una excepción. El principal desafío es que pocos tenemos el tiempo suficiente para investigar su funcionamiento y deducir buenas prácticas al respecto.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Gracias a dos artículos publicados en ADO.NET TEAM Blog sobre rendimiento del Entity Framework &lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[1]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt; &lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/11/exploring-the-performance-of-the-ado-net-entity-framework-part-2.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[2]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt;y la fantástica FAQ de Entity Framework &lt;/font&gt;&lt;a href="http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[3]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt; recopilada por Danny Simmons en su blog &lt;i style="mso-bidi-font-style:normal;"&gt;Sys.Data.Objects dev guy&lt;/i&gt; se pueden extraer algunas buenas prácticas para mejorar el rendimiento en Entity Framework, especialmente para aquellos entornos con contextos de tiempo de vida cortos.&lt;/font&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font size="4"&gt;&lt;font color="#4f81bd"&gt;&lt;font face="Cambria"&gt;Buenas prácticas para mejorar la eficiencia en escenarios con &lt;i style="mso-bidi-font-style:normal;"&gt;Short Lived Contexts&lt;/i&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/h2&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Vamos a centrarnos en los siguientes aspectos:&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpFirst" style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;span style="FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;span style="mso-list:Ignore;"&gt;&lt;font size="3"&gt;·&lt;/font&gt;&lt;span style="FONT:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Calibri" size="3"&gt;Acelerar la creación de ObjectContexts&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpMiddle" style="MARGIN:0cm 0cm 0pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;span style="FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;span style="mso-list:Ignore;"&gt;&lt;font size="3"&gt;·&lt;/font&gt;&lt;span style="FONT:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Calibri" size="3"&gt;Afinar el ObjectStateManager&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpLast" style="MARGIN:0cm 0cm 10pt 36pt;TEXT-INDENT:-18pt;mso-list:l0 level1 lfo1;"&gt;&lt;span style="FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;span style="mso-list:Ignore;"&gt;&lt;font size="3"&gt;·&lt;/font&gt;&lt;span style="FONT:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Calibri" size="3"&gt;Optimizar la ejecución de consultas en LINQ to Entities&lt;/font&gt;&lt;/p&gt;
&lt;h3 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="3"&gt;Acelerando la creación de ObjectContext&lt;/font&gt;&lt;/h3&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Uno de los principales problemas a lo que nos enfrentamos es que crear un ObjectContext es una actividad costosa, especialmente la primera vez. En una aplicación con short lived context se suele crear y desechar un ObjectContext prácticamente por petición a la lógica de negocio. En una sesión o en un petición desde el interface es fácil tener una o más invocaciones a la fachada de la lógica de negocio que utilizan varios ObjectContexts. Si multiplicamos estas instanciaciones por peticiones concurrentes, el número de ObjectContext creado se dispara. El EF proporciona alguna optimización al respecto &lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[1]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt;; la primera vez que se crea un ObjectContext se cachea la información de metadata del modelo que se construye a partir de los archivos CSDL, MSL y SSDL. Esta información se cachea y se comparte a nivel de dominio de aplicación (38% del tiempo). Otra gran parte del tiempo de esta primera instanciación se emplea en la creación de la vista abstracta de la base de datos en memoria (56% del tiempo), que también se cachea.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Solo el 7% del tiempo se emplea en la materialización (por ejemplo un DBReader obteniendo los datos físicos)&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;En la práctica tenemos que una primera ejecución de un método con una consulta a través de EF es del orden de 300 veces más lenta que las consultas sucesivas. Las consultas en caliente son relativamente rápidas y el 74% del tiempo se emplea en la materialización de la consulta y solo el 4,13% en la creación del ObjectContext.&lt;/font&gt;&lt;/p&gt;
&lt;h4 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;em&gt;&lt;font face="Cambria" color="#4f81bd"&gt;Antipatrones&lt;/font&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Si a alguien se le ocurre compartir un único ObjectContext por dominio de aplicación debe saber que no es una buena idea porque el EF no es &lt;i style="mso-bidi-font-style:normal;"&gt;thread Safe&lt;/i&gt;, como la gran mayoría de clases del framework, si bien podría implementarse un mecanismo de bloqueo propio. Ver &lt;/font&gt;&lt;a href="http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[3]&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Si estamos en una aplicación ASP.NET puede parecernos tentador guardar en la sesión el ObjectContext pero tampoco es una buena idea ya que el tamaño de la sesión crecería enormemente y su correcta serialización tampoco es trivial. Ver &lt;/font&gt;&lt;a href="http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[3]&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;em&gt;&lt;font face="Cambria" color="#4f81bd"&gt;Buena práctica&lt;/font&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;La principal aproximación para rebajar el tiempo de creación del contexto es en su primera instanciación. Se puede reducir el tiempo de generación de la vista (un 58% del tiempo de creación) teniéndola compilada previamente.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Para ello deberemos ejecutar edmgen.exe con la opción /mode:ViewGeneration, esto crea un fichero de código que puede ser incluido en nuestro proyecto. &lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;En las pruebas realizadas en &lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[1]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt; se obtuvo un descenso del 28% de tiempo en la primera instanciación. La desventaja &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;es que si hacemos cambios en los archivos de metada del EDM necesitaremos recompilar la aplicación. Pero si eso podemos asumirlo, deberíamos aplicar siempre esta optimización. &lt;/font&gt;&lt;/p&gt;
&lt;h3 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="3"&gt;Afinando el ObjectStateManager&lt;/font&gt;&lt;/h3&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Cada ObjectContext tiene un ObjectStateManager que, entre otras tareas, mantiene el estado correcto de los objetos cacheados en memoria. Por defecto si se recuperan nuevas entidades del almacén de datos a través de una consulta, ESQL o LINQ &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;to Entities, EF solo cargará aquellas que no están aun en memoria, llevando un seguimiento efectivo de las entidades en memoria con respecto a su persistencia física en el almacén de datos.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Llevar este seguimiento o &lt;i style="mso-bidi-font-style:normal;"&gt;tracking &lt;/i&gt;es útil en aquellos contextos dónde realicemos varias consultas que impliquen un mismo conjunto de entidades.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Pero lo más normal es disponer de abundantes métodos en nuestra fachada que simplemente recuperan una enumeración de entidades para ser enlazadas a su vez a un control visual como un GridView o un DropDownList. &lt;/font&gt;&lt;/p&gt;
&lt;h4 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;em&gt;&lt;font face="Cambria" color="#4f81bd"&gt;Buena práctica&lt;/font&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Es posible modificar esta política de seguimiento del ObjectStateManager para un&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;ObjectQuery concreto, desactivándola en casos como el anteriormente descrito, obteniendo una ligera mejora en los tiempos. &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;Un ObjectQuery tiene un atributo llamado MergeOption que es un enum con los valores: AppendOnly, NoTracking, OverwriteChanges, PreserveChanges. Con la opción MergeOption.NoTracking no se hacen comprobaciones de seguimiento.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Por ejemplo:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;using&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; (&lt;span style="COLOR:#2b91af;"&gt;MyTravelPostEntities&lt;/span&gt; entities = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;MyTravelPostEntities&lt;/span&gt;())&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;entities.BlogPosts.MergeOption = &lt;span style="COLOR:#2b91af;"&gt;MergeOption&lt;/span&gt;.NoTracking;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:#2b91af;"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;BlogPost&lt;/span&gt;&amp;gt; postQuery = (&lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; bp &lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; entities.BlogPosts&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;where&lt;/span&gt; bp.Comments.Count() &amp;gt; 0&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; bp);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="COLOR:#2b91af;"&gt;BlogPost&lt;/span&gt; post = postQuery.First();&lt;br /&gt;&lt;/span&gt;&lt;font face="Calibri" size="3"&gt;…&lt;/font&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;De todas formas, según los tiempos obtenidos en los artículos referenciados, la comprobación de seguimiento por parte del ObjectStateManager&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;solo abarca de un 1% a un 3% del tiempo total de la consulta. &lt;/font&gt;&lt;/p&gt;
&lt;h3 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="3"&gt;Optimizando las consultas en LINQ &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;to Entities&lt;/font&gt;&lt;/h3&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;De la misma forma que se cachean los metadatos también se cachean las consultas a nivel de Entity Framework, por eso las segundas ejecuciones de la misma consulta son más rápidas. Al igual que el caché de metadatos, el caché de consultas tienen un ámbito global de dominio de aplicación.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Ojo, no confundir este caché de consultas de EF con el caché de planes de ejecución de consultas SQL en SQL Server u otro gestor de base de datos relacional.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Si bien una consulta en ESQL se cachea prácticamente toda, no ocurre lo mismo con una consulta en LINQ To Entities, algunas partes tienen que construirse de nuevo en las ejecuciones sucesivas; por ejemplo el árbol de expresión resultante tiene que ser calculado o compilado en memoria en tiempo de ejecución y para cada invocación de la consulta LINQ to Entities necesita ser reconstruido. &lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Lo ideal sería que estas consultas LINQ solo se tuvieran que compilar una vez. &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;Es posible hacerlo utilizando, por ejemplo, una función estática anónima&lt;/font&gt;&lt;a class="" title="_ftnref1" style="mso-footnote-id:ftn1;" href="http://geeks.ms/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost#_ftn1" name="_ftnref1"&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="mso-special-character:footnote;"&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="FONT-SIZE:11pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:Calibri;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-ansi-language:ES;mso-fareast-language:EN-US;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-theme-font:minor-bidi;mso-bidi-language:AR-SA;"&gt;&lt;font color="#0000ff"&gt;[1]&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt; que actúe de delegado. Dando lugar a consultas compiladas LINQ; que son más rápidas que las consultas LINQ To Entities tradicionales siempre que se ejecuten con cierta frecuencia.&lt;/font&gt;&lt;/p&gt;
&lt;h4 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;em&gt;&lt;font face="Cambria" color="#4f81bd"&gt;Buena práctica&lt;/font&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Supongamos esta petición con contexto de tiempo de vida corto (obsérvese la aplicación de la buena práctica del apartado anterior):&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;using&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; (PFCNetEntities ctx = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; PFCNetEntities())&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;ctx.Projects.MergeOption = ctx.&lt;span style="COLOR:#2b91af;"&gt;MergeOption&lt;/span&gt;.NoTracking;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:#2b91af;"&gt;IQueryable&lt;/span&gt;&amp;lt;ProjectRegister&amp;gt; query =&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;from&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; project &lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; ctx.Projects&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;where&lt;/span&gt; project.User.UserName == UserLogin&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; project;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;pr = query.FirstOrDefault&amp;lt;ProjectRegister&amp;gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Para que no sea necesario volver a construir el árbol de expresión de la consulta LINQ to Entities utilizamos una expresion lambda&lt;sup&gt;1&lt;/sup&gt; estática que se ejecute al comienzo del tiempo de vida de nuestro dominio de aplicación, obsérvese que admite el paso del parámetro UserLogin para filtrar la consulta&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;private&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;PFCNetEntities, &lt;span style="COLOR:#2b91af;"&gt;String&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;IQueryable&lt;/span&gt;&amp;lt;ProjectRegister&amp;gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;compiledProjectRegisterByUserQuery = &lt;span style="COLOR:#2b91af;"&gt;CompiledQuery&lt;/span&gt;.Compile(&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(PFCNetEntities ctx, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; UserLogin) =&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; project &lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; ctx.ProjectRegister&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;where&lt;/span&gt; project.User.UserName == UserLogin&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; project));&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt; ProjectRegister GetProjectRegisterByUser(&lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; UserLogin)&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ProjectRegister pr = &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;using&lt;/span&gt; (PFCNetEntities ctx = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; PFCNetEntities())&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ctx.ProjectRegister.MergeOption = &lt;span style="COLOR:#2b91af;"&gt;MergeOption&lt;/span&gt;.NoTracking;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pr = compiledProjectRegisterByUserQuery(ctx,&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;UserLogin).FirstOrDefault&amp;lt;ProjectRegister&amp;gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; pr;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:9pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;mso-no-proof:yes;mso-bidi-font-size:10.0pt;"&gt;&amp;nbsp;&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;En las pruebas realizadas en &lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/11/exploring-the-performance-of-the-ado-net-entity-framework-part-2.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[2]&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri" size="3"&gt; se observa que para la primera ejecución de una consulta LINQ frente a una consulta LINQ Compilada se obtiene paradójicamente que la consulta LINQ es un 23% más rápida. Si bien en sucesivas ejecuciones (suponemos siempre que en nuestro escenario empresarial las consultas son invocadas frecuentemente) se obtiene que las consultas LINQ compiladas, que por ejemplo tienen un filtro, son del orden &lt;b style="mso-bidi-font-weight:normal;"&gt;de un 80% más rápidas&lt;/b&gt;. Este dato es importante porque es una mejora significativa en los tiempos de ejecución. Siendo muy recomendable utilizar LINQ to Entities compiladas en aquellas consultas que sabemos a priori que van a tener una alta tasa de invocaciones.&lt;/font&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="4"&gt;Resumen&lt;/font&gt;&lt;/h2&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Los principales patrones arquitectónicos para aplicaciones empresariales implican el uso de contextos de tiempo de vida corto, especialmente en aquellas aplicaciones ASP.NET, servicios web o WCF. Se han presentado tres buenas prácticas para mejorar la eficiencia en este tipo de escenarios. &lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;La primera reduce el tiempo de creación del primer ObjectContext en un dominio de aplicación. &lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;La segunda desactiva la comprobación de seguimiento para el ObjectStateManager en aquellas operaciones de mera recuperación de datos. &lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;La tercera y última buena práctica define un patrón para utilizar consultas LINQ To Entities compiladas.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Por último, este post está totalmente abierto y con vuestras aportaciones y lo que vaya surgiendo de los blogs de ADO.NET y System.Data.Object Dev Guy lo iré ampliando hasta tener un catálogo de buenas prácticas que mejoren la eficiencia de EF en escenarios comunes como los de contextos con tiempo de vida cortos.&lt;/font&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;font face="Cambria" color="#4f81bd" size="4"&gt;Referencias&lt;/font&gt;&lt;/h2&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;/font&gt; 
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;WIDTH:792px;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;HEIGHT:152px;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;mso-border-insideh:none;mso-border-insidev:none;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:26.7pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;"&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[1]&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:405.5pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="mso-ansi-language:EN;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Exploring the Performance of the ADO.NET Entity Framework - Part 1&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"&gt;&lt;font face="Calibri" size="3"&gt;http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;(04/02/2008)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="mso-yfti-irow:1;"&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:26.7pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;"&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/11/exploring-the-performance-of-the-ado-net-entity-framework-part-2.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[2]&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:405.5pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="mso-ansi-language:EN;"&gt;Exploring the Performance of the ADO.NET Entity Framework – Part 2&lt;/span&gt;&lt;/b&gt;&lt;span style="mso-ansi-language:EN-US;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2008/02/11/exploring-the-performance-of-the-ado-net-entity-framework-part-2.aspx"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font face="Calibri" size="3"&gt;http://blogs.msdn.com/adonet/archive/2008/02/11/exploring-the-performance-of-the-ado-net-entity-framework-part-2.aspx&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt; &lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;(11/02/2008)&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="mso-yfti-irow:2;mso-yfti-lastrow:yes;"&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:26.7pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;"&gt;&lt;a href="http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx"&gt;&lt;font face="Calibri" size="3"&gt;[3]&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#f0f0f0;PADDING-RIGHT:5.4pt;BORDER-TOP:#f0f0f0;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0cm;BORDER-LEFT:#f0f0f0;WIDTH:405.5pt;PADDING-TOP:0cm;BORDER-BOTTOM:#f0f0f0;BACKGROUND-COLOR:transparent;"&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="mso-ansi-language:EN;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;EF FAQ updated - v0.3&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="mso-ansi-language:EN;"&gt;&lt;a href="http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx"&gt;&lt;font face="Calibri" size="3"&gt;http://blogs.msdn.com/dsimmons/archive/2008/01/04/ef-faq-updated-v0-3.aspx&lt;/font&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;(04/02/2008)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="mso-ansi-language:EN;"&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt; 
&lt;div style="mso-element:footnote-list;"&gt;&lt;br /&gt;&lt;font face="Calibri" size="3"&gt;
&lt;hr align="left" /&gt;
&lt;/font&gt;
&lt;div id="ftn1" style="mso-element:footnote;"&gt;
&lt;p class="MsoFootnoteText" style="MARGIN:0cm 0cm 0pt;"&gt;&lt;a class="" title="_ftn1" style="mso-footnote-id:ftn1;" href="http://geeks.ms/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost#_ftnref1" name="_ftn1"&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="mso-special-character:footnote;"&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:Calibri;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-ansi-language:ES;mso-fareast-language:EN-US;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-theme-font:minor-bidi;mso-bidi-language:AR-SA;"&gt;&lt;font color="#0000ff"&gt;[1]&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;font face="Calibri"&gt; para aquellos que no les suene, una función anónima es una expresión típica del lambda cálculo introducida en C# 3.0 y que ha mejorado la forma de definir delegados. &lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb549151.aspx"&gt;&lt;font face="Calibri"&gt;Más información&lt;/font&gt;&lt;/a&gt;&lt;font face="Calibri"&gt;.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=71344" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="Best Practices" scheme="http://geeks.ms/blogs/quintas/archive/tags/Best+Practices/default.aspx" /><category term="ADO.NET Entity Framework Beta" scheme="http://geeks.ms/blogs/quintas/archive/tags/ADO.NET+Entity+Framework+Beta/default.aspx" /><category term="Patrones" scheme="http://geeks.ms/blogs/quintas/archive/tags/Patrones/default.aspx" /><category term="Short Lived Contexts" scheme="http://geeks.ms/blogs/quintas/archive/tags/Short+Lived+Contexts/default.aspx" /></entry><entry><title>Eventos .NUGG en Febrero: ADO.NET Entity Framework y SQL Server 2008</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/02/12/eventos-nugg-en-febrero-ado-net-entity-framework-y-sql-server-2008.aspx" /><id>/blogs/quintas/archive/2008/02/12/eventos-nugg-en-febrero-ado-net-entity-framework-y-sql-server-2008.aspx</id><published>2008-02-12T15:19:00Z</published><updated>2008-02-12T15:19:00Z</updated><content type="html">&lt;div&gt;&lt;font face="Tahoma" color="#000000" size="2"&gt;Os anuncio la proximidad de dos interesantísimos ;-) eventos .NUGG (.Net User Group Galicia) en A Coruña.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;Es necesario el registro previo.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" color="#808080" size="1"&gt;Viernes 22 de Febrero de 17:00 a 19:30&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;.Net 3.5: ADO.NET Entity Framework&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;font face="Tahoma" color="#808080" size="1"&gt;&lt;strong&gt;Eduardo Quintás &lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;&lt;a class="" href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032369580&amp;amp;Culture=es-ES" target="_blank"&gt;http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032369580&amp;amp;Culture=es-ES&lt;/a&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font size="2"&gt;
&lt;div&gt;&lt;font face="Tahoma" color="#808080" size="1"&gt;Viernes 29 de Febrero de 17:00 a 19:30&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;More Magic - SQL Server 2008&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;font face="Tahoma" color="#808080" size="1"&gt;&lt;strong&gt;Pablo Álvarez Doval &lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;u&gt;&lt;font face="Tahoma" color="#800080"&gt;&lt;a class="" href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032369582&amp;amp;Culture=es-ES" target="_blank"&gt;http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032369582&amp;amp;Culture=es-ES&lt;/a&gt;&lt;/font&gt;&lt;/u&gt;&lt;/div&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;Se celebran en los aularios del CUFIE en el edificio Xoana Capdevielle del campus de Elviña.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;Aqui teneis &lt;/font&gt;&lt;font face="Tahoma"&gt;&lt;a class="" href="http://maps.live.com/default.aspx?v=2&amp;amp;cp=43.335495~-8.403436&amp;amp;style=r&amp;amp;lvl=16&amp;amp;tilt=-90&amp;amp;dir=0&amp;amp;alt=-1000&amp;amp;cid=4EA949064454891C!539&amp;amp;encType=1" target="_blank"&gt;su localización&lt;/a&gt;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="Tahoma" size="2"&gt;Espero veros a alguno!&lt;/font&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=70901" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="ADO.Net" scheme="http://geeks.ms/blogs/quintas/archive/tags/ADO.Net/default.aspx" /><category term="SQL Server 2008" scheme="http://geeks.ms/blogs/quintas/archive/tags/SQL+Server+2008/default.aspx" /><category term="Entity Framework" scheme="http://geeks.ms/blogs/quintas/archive/tags/Entity+Framework/default.aspx" /><category term="Evento" scheme="http://geeks.ms/blogs/quintas/archive/tags/Evento/default.aspx" /><category term=".Net Framework 3.5" scheme="http://geeks.ms/blogs/quintas/archive/tags/.Net+Framework+3.5/default.aspx" /><category term=".NUGG" scheme="http://geeks.ms/blogs/quintas/archive/tags/.NUGG/default.aspx" /></entry><entry><title>Entity Framework BETA 3</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2008/01/03/entity-framework-beta-3.aspx" /><id>/blogs/quintas/archive/2008/01/03/entity-framework-beta-3.aspx</id><published>2008-01-03T10:47:00Z</published><updated>2008-01-03T10:47:00Z</updated><content type="html">&lt;p&gt;El mes pasado, el ADO.NET Team, tal como nos comentaba &lt;a class="" href="http://geeks.ms/blogs/elbruno/archive/2007/12/07/vs2008-ado-net-entity-framework-beta-3.aspx" target="_blank"&gt;elbruno&lt;/a&gt;, publlicó una nueva release beta del ADO.NET Entity Framework (EF en adelante) y una nueva CPT de las herramientas visuales para la generación del modelo de datos de entidades (EDM).&lt;/p&gt;
&lt;p&gt;Como sabeis el EF es el primer ORM de Microsoft para la tecnología ADO.NET y conociendo previamente NHIbernate, la verdad es que ofrece una característica que hara las delicias de los programadores: LINQ to Entities. Es posible aprovechar toda la potencia de LINQ para consultar las entidades de nuestro modelo de forma efectiva, rápida y homogenea, siguiendo el ideal de Microsoft de aprender un único lenguaje de consulta de datos (LINQ) para múltiples tipos de datos (colecciones en memoria, XML, registro de windows, etc.) que se compila (y por tanto se comprueban los tipos) y no se resuelve en tiempo de ejecución como los largos strings con consultas SQL o HQL en NHibernate que eran culpables de bastantes errores en tiempo de ejecución y que requerían un depurado exhaustivo y algo tedioso.&lt;/p&gt;
&lt;p&gt;Si quereis probarlo necesitareis por un lado VisualStudio 2008, podeis descargaros un Trial desde &lt;a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=83C3A1EC-ED72-4A79-8961-25635DB0192B&amp;amp;displaylang=en"&gt;aquí&lt;/a&gt;&amp;nbsp;o también el &lt;a class="" href="http://www.microsoft.com/express/download/"&gt;VisualStudio 2008 Express&lt;/a&gt; que es gratuito y luego instalar el &lt;a class="" href="http://go.microsoft.com/fwlink/?LinkId=104981"&gt;Entity Framework Beta 3&lt;/a&gt;. Después es necesario instalar el &lt;a class="" href="http://go.microsoft.com/fwlink/?LinkID=104985"&gt;XML Editor QFE&lt;/a&gt; para finalmente proceder a la instalación del &lt;a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=D8AE4404-8E05-41FC-94C8-C73D9E238F82&amp;amp;displaylang=en"&gt;Entity Designer CTP2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;También os va a hacer falta tener instalado SQL Server 2005 (vale la &lt;a class="" href="http://www.microsoft.com/downloads/details.aspx?displaylang=es&amp;amp;FamilyID=220549B5-0B07-4448-8848-DCC397514B41"&gt;edición express&lt;/a&gt;) para poder ejecutar los ejemplos &lt;a class="" href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=adonetsamples&amp;amp;ReleaseId=8858"&gt;disponibles en codeplex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Como comentaba Bruno mucha gente se pregunta cuándo utilizar&amp;nbsp;EF y cuando LINQ to SQL. La principal diferencia, a mi modo de ver, es que LINQ to SQL solo trabaja contra SQL Server, algo a tener en cuenta pues EF ofrece más proveedores de datos. Actualmente y según&amp;nbsp;un &lt;a class="" href="http://blogs.msdn.com/adonet/archive/2007/12/17/the-ado-net-entity-framework-not-just-for-sql-server.aspx"&gt;post reciente&lt;/a&gt;&amp;nbsp;del ADO.NET Team Blog ya existen proveedores&amp;nbsp;para&amp;nbsp;Oracle, MySQL, PostgreSQL, SQLite, Informix, Ingres, Sybase, DB2, Progress, VistaDB, SQL Anywhere&amp;nbsp;así como un bridge para drivers ODBC y JDBC. También se ha anunciado que pronto estará disponible un proveedor para Firebird. Ya en épocas tempranas al desarrollo de EF se ofreció un ADO.NET Sample Provider que ayudaba de desarrolladores de proveedores de acceso a datos implementar sus propios proveedores de EF. Tanto que en el TechED celebrado en Junio de 2007 en Orlando, Brent Goss del equipo de DB2 de IBM mostró un ejemplo con 101 consultas de LINQ to Entities sobre un SGBD DB2.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A todos aquellos que esteis interesados en ORMs o trabajeis con ellos os animo a que echeis un ojo al EF y saqueis vuestras propias conclusiones... para mi es uno de los productos de desarrollo en acceso a datos más interesantes actualmente.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=61033" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Artículo "Visualización de grandes conjuntos de datos en ASP.NET" publicado en DotNetManía: Correcciones y recursos.</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/11/13/art-237-culo-quot-visualizaci-243-n-de-grandes-conjuntos-de-datos-en-asp-net-quot-publicado-en-dotnetman-237-a-correcciones-y-recursos.aspx" /><id>/blogs/quintas/archive/2007/11/13/art-237-culo-quot-visualizaci-243-n-de-grandes-conjuntos-de-datos-en-asp-net-quot-publicado-en-dotnetman-237-a-correcciones-y-recursos.aspx</id><published>2007-11-13T21:40:00Z</published><updated>2007-11-13T21:40:00Z</updated><content type="html">&lt;p&gt;En artículo publicado en DotNetManía de este mes, comentaba en un punto que &lt;em&gt;&lt;font size="1"&gt;&amp;quot;&lt;/font&gt;&lt;span style="FONT-SIZE:11pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-ansi-language:ES-TRAD;mso-fareast-font-family:Calibri;mso-fareast-language:EN-US;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-bidi-language:AR-SA;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;... &amp;nbsp;también se planteó la posibilidad de utilizar procedimientos almacenados, aprovechando que se compilan y su plan de ejecución nunca se descarta de un caché ...&lt;/span&gt;&amp;quot;. &lt;/em&gt;Que aunque no afecta a la esencia del artículo, para nada es correcto. Los procedimientos almacenados en SQL Server no se compilan. Se compila su plan de ejecución y es tratado en la caché como un elemento más con las mismas politicas que por ejemplo una entrada marcada como prepared_query. Esta compilación se lleva acabo en la primera invocación del procedimiento almacenado y puede ser recompilado a lo largo del tiempo por diversos motivos. Si os interesa podeis consultar el post &amp;quot;&lt;a href="http://geeks.ms/blogs/quintas/archive/2007/11/13/cach-233-de-planes-de-ejecuci-243-n-en-sql-server-2005-y-comportamiento-de-los-procedimientos-almacenados.aspx"&gt;&lt;font color="#fa4520"&gt;Caché de planes de ejecución en SQL Server 2005 y comportamiento de los procedimientos almacenados&lt;/font&gt;&lt;/a&gt;&amp;quot; dónde explico con detalle preguntas lógicas sobre el rendimiento de los procedimientos almacenados con consultas y consultas marcadas como prepared_query.&lt;/p&gt;
&lt;p&gt;Por otra parte a todos aquellos que esteis interesados en obtener el código fuente del artículo podeis descargarlo haciendo clic&lt;a class="" href="http://www.dotnetmania.com/Articulos/042/Apoyo/GridViewSample.zip"&gt; aquí&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=49967" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="SQL Server 2005" scheme="http://geeks.ms/blogs/quintas/archive/tags/SQL+Server+2005/default.aspx" /><category term="ADO.Net" scheme="http://geeks.ms/blogs/quintas/archive/tags/ADO.Net/default.aspx" /><category term="Gridview" scheme="http://geeks.ms/blogs/quintas/archive/tags/Gridview/default.aspx" /><category term="ASP.NET" scheme="http://geeks.ms/blogs/quintas/archive/tags/ASP.NET/default.aspx" /></entry><entry><title>Caché de planes de ejecución en SQL Server 2005 y comportamiento de los procedimientos almacenados</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/11/13/cach-233-de-planes-de-ejecuci-243-n-en-sql-server-2005-y-comportamiento-de-los-procedimientos-almacenados.aspx" /><id>/blogs/quintas/archive/2007/11/13/cach-233-de-planes-de-ejecuci-243-n-en-sql-server-2005-y-comportamiento-de-los-procedimientos-almacenados.aspx</id><published>2007-11-13T20:46:00Z</published><updated>2007-11-13T20:46:00Z</updated><content type="html">&lt;p&gt;Esta mañana Iván me preguntaba sobre una afirmación que ponía en las conclusiones de artículo &amp;quot;Visualización de grandes conjuntos de datos en ASP.NET&amp;quot; publicado en la &lt;a class="" href="http://blogs.msdn.com/sqlprogrammability/archive/2006/05/04/Ketan-Duvedi.aspx"&gt;DotNetMania&lt;/a&gt; de este mes. Decía &lt;em&gt;&lt;font face="arial,helvetica,sans-serif"&gt;&lt;font size="1"&gt;&amp;quot;&lt;span style="FONT-SIZE:11pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-ansi-language:ES-TRAD;mso-fareast-font-family:Calibri;mso-fareast-language:EN-US;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-bidi-language:AR-SA;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;... &amp;nbsp;también se planteó la posibilidad de utilizar procedimientos almacenados, aprovechando que se compilan y su plan de ejecución nunca se descarta de un caché ...&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&amp;quot;. &lt;/em&gt;Esto es &lt;strong&gt;totalmente incorrecto&lt;/strong&gt; y quizas me deje llevar por mis viejas experiencias con Informix y 4GL. &lt;img src="http://geeks.ms/emoticons/emotion-4.gif" alt="Stick out tongue" /&gt;&lt;/p&gt;
&lt;p&gt;Además nos empezaron a surgir bastantes dudas sobre el comportamiento de los planes de ejecución de los procedimientos almacenados. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;¿Los Procedimientos almacenados se compilan? ¿cuándo lo hacen?&lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;¿Hay alguna diferencia en la forma de tratar la caché de los planes de ejecución marcados como prepared_query o stored proc?&lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&lt;font face="tahoma" size="2"&gt;&lt;strong&gt;¿Cuál es el tamaño del caché de planes de ejecución?¿Cuál es la política para descartar elementos?&lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;¿Cuándo se invalida el plan de caché, datos etc y se precisa de recompilación?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;Documentación consultada&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Primero miré algunos blogs sobre SQL Server según los devolvía google y acabé leyendo bastantes opiniones que se contradecían unas a otras relacionadas con las preguntas anteriores. En algún sitio ponían que los procedimientos almacenados eran compilados en el momento de ser creados... en fin... &lt;/p&gt;
&lt;p&gt;&lt;a class="" href="http://www.microsoft.com/technet/prodtechnol/sql/2005/recomp.mspx"&gt;Batch Compilation, Recompilation, and Plan Caching Issues in SQL Server 2005.&lt;/a&gt; Explica como funciona el caché de planes de ejecución con detalle para&amp;nbsp;batchs (lotes) con sentencias SQL, incluidos procedimientos almacenados. También explica las diferencias principales de SQL Server 2000 y 2005 al respecto.&lt;/p&gt;
&lt;p&gt;En el post &lt;a id="ctl00___ctl00___Month___postlist___EntryItems_ctl07_PostTitle" href="http://blogs.msdn.com/sqlprogrammability/archive/2007/01/16/9-0-memory-pressure-limits.aspx"&gt;9.0 Memory Pressure Limits&lt;/a&gt;&amp;nbsp;publicado en el blog &lt;a class="headermaintitle" id="bp___ctl00___bth___BlogTitle" href="http://blogs.msdn.com/sqlprogrammability/default.aspx"&gt;SQL Programmability &amp;amp; API Development Team Blog&lt;/a&gt;, que siempre recomiendo&amp;nbsp;para entender bien cómo funciona SQL Server por debajo encontré información adicional sobre&amp;nbsp;el número de cachés de planes de ejecución y cómo se&amp;nbsp;comportan&amp;nbsp;en condiciones de&amp;nbsp;poca memoria disponible.&amp;nbsp;En el post &lt;a class="" href="http://blogs.msdn.com/sqlprogrammability/archive/2006/05/04/Ketan-Duvedi.aspx"&gt;What are the different cached objects in the plan cache?&lt;/a&gt;&amp;nbsp;Ketan Duvedi nos explica los diversos tipos de objetos que se almacenan en las cachés de planes de ejecución&lt;/p&gt;
&lt;p&gt;Por último en &lt;a class="" href="http://technet.microsoft.com/es-es/sqlserver/bb331794.aspx"&gt;SQL Server Best Practices&lt;/a&gt;&amp;nbsp;encontré una colección de enlaces a whitepapers y recursos con buenas prácticas para SQL Server (especialmente 2005)&lt;/p&gt;
&lt;p&gt;Antes de responder a las preguntas conviene entender lo que es un batch o un lote de sentencias en SQL Server: &lt;font face="Tahoma"&gt;Entenderemos por Batch o lote por un conjunto de sentencias SELECT, INSERT, DELETE, UPDATE, llamadas a prodecimientos almacenados. También se incluye todas las sentencias intermedias de Transact-sql, sentencias GRANT, DENY, etc... es la unidad de compilación e inserción en el caché pero cada sentencia individual. El batch es la unidad de compilación de plan de ejecución y cómo tal se guarda en la caché de planes de ejecución. Para cada sentencia del batch se guarda también su plan de ejecución en la caché, pero jerárquicamente dependen del batch.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font face="Tahoma"&gt;Los Procedimientos almacenados se compilan? ¿cuándo lo hacen?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Tahoma"&gt;Pues primera discrepancia con lo que dije: los procedimientos almacenados estríctamente hablando &lt;strong&gt;no se compilan&lt;/strong&gt;. Lo que se compila es el plan de ejecución y se almacena en la caché de planes de&amp;nbsp;ejecución. El plan de ejecución se&amp;nbsp;crea la primera vez que&amp;nbsp;se invoca el procedimiento almacenado.&amp;nbsp;&amp;nbsp;Y es tratado como una entrada más en la caché de los planes de ejecución, por tanto puede llegar a ser decartado. Por cierto los batch no debería superarse los 8KB de tamaño (ojo con los literales grandes, BLOBs, etc.) si queremos que entre la caché de planes de ejecución. Una mejora importante de SQL Server 2005 respecto a 2000 es que cuando es necesario recompilar el plan de ejecución de una sentencia en un batch (por diversos motivos, porque ha cambiado el esquema, etc.) se recompila solo esa sentencia y no el batch completo, como ocurría en SQL Server 2000.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Tahoma"&gt;&lt;strong&gt;¿Hay alguna diferencia en la forma de tratar la caché de los planes de ejecución marcados como prepared_query o stored proc?&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;font face="Tahoma"&gt;&lt;font face="tahoma" size="2"&gt;A parte de ser objetos distintos (consulta parametrizada vs. proc. almacenado), en principio parece que no, según la documentación consultada&amp;nbsp;ambos favorecen la reutilización de su plan de ejecución. De hecho las consultas marcadas como prepared query se han lanzado con SQLPrepare(), al igual que sp_executesql favorecen la reutilización del Plan. Los proveedores de OleDB y Odbc lo utilizan y como comprobé el proveedor nativo de SqlServer de ADO.Net con este hecho no hay diferencia entre tener una consulta prepared (parametrizada) y un procedimiento almacenado que realiza dicha consulta pasando los parámetros. Aunque parezca poco importante es muy revelador porque aun hay mucha gente que introduce consultas en procedimientos almacenados porque cree que es la única manera&amp;nbsp;de aumentar el rendimiento al asegurar la reutilización del plan de ejecución.&lt;/font&gt;&lt;/font&gt;&lt;font face="Tahoma"&gt; 
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;Y puede que las consultas preparadas tengan mejor rendimiento que las incluidas en un procedimiento almacenado por la siguiente razón: Si un procedimiento almacenado se ejecuta en una base de datos D1, su plan de ejecución no es reutilizado si se ejecuta en una base de datos distinta D2. En cambio las consultas ad-hoc, las prepared y las dinámicas SI.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;Los planes de ejecución se reutilizan entre usuarios, los contextos de ejecución (p.e. unos valores de parámetros determinados) no porque son afines a la sesión del usuario (lógicamente). Así que, aunque se cachean, el impacto es más bien escaso. Por eso es muy importante envíar consultas con parámetros explícitos o crear procedimientos almacenados, si bien SQL Server 2005 tiene una característica de autoparametrización de consultas que se repiten.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;Es MUY IMPORTANTE utilizar nombres calificados a la hora de referenciar objetos de la base de datos. En otro caso no podrán SER REUTILIZADOS entre usuarios.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;Por ejemplo: Supongamos que hay dos tablas&amp;nbsp;foo: marta.foo y&amp;nbsp;jaime.foo en una misma base de&amp;nbsp;datos. El plan de ejecución &amp;quot;select * from users&amp;quot; para el usuario marta no sería compartido con el de jaime. Son tablas distintas. También ocurre cuando solo tenemos una tabla, por eso es importante hacer siempre &amp;quot;select * from dbo.users&amp;quot;. En ese caso el UID coincide (-2) y puede ser compartida entre distintos usuarios.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;¿Cual es el tamaño del caché de planes de ejecución?¿cúal es la política para descartar elementos?&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;/strong&gt;Para empezar no hay un solo caché de planes de ejecución... realmente hay cuatro, pero dos son los importantes: hay uno para las consultas marcadas como ad-hoc y para las marcadas como prepared query y otro para los procedimientos almacenados. Podríamos pensar que estaría bueno balancear y crear prepared queries y proc. alamacenados para&amp;nbsp;llenar equitativamente las dos cachés. Es una tontería, porque en el caso de que uno se llene y queden libres en el otro se le asigna el espacio sobrante al que le hace falta.&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;Con la siguiente consulta obtenemos los siguientes tamaños de entradas para cada plan de caché:&lt;br /&gt;&lt;/font&gt;&lt;font face="tahoma" size="2"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:Courier New;"&gt;select&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&lt;font color="#0000ff" size="2"&gt;name&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;type&lt;/font&gt;&lt;font color="#808080" size="2"&gt;, &lt;/font&gt;buckets_count &lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; &lt;span style="COLOR:green;"&gt;sys.dm_os_memory_cache_hash_tables&lt;/span&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:Courier New;"&gt;where&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt; &lt;span style="COLOR:blue;"&gt;type&lt;/span&gt; &lt;span style="COLOR:gray;"&gt;in&lt;/span&gt; &lt;span style="COLOR:gray;"&gt;(&lt;/span&gt;&lt;span style="COLOR:red;"&gt;&amp;#39;CACHESTORE_OBJCP&amp;#39;&lt;/span&gt; &lt;span style="COLOR:gray;"&gt;,&lt;/span&gt; &lt;span style="COLOR:red;"&gt;&amp;#39;CACHESTORE_SQLCP&amp;#39;&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;,&lt;/span&gt; &lt;span style="COLOR:red;"&gt;&amp;#39;CACHESTORE_PHDR&amp;#39;&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;,&lt;/span&gt; &lt;span style="COLOR:red;"&gt;&amp;#39;CACHESTORE_XPROC&amp;#39;&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;span style="COLOR:gray;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;span style="COLOR:gray;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="tahoma" size="2"&gt;Por ejemplo en mi sistema (SQl Server Express 2005)&lt;/font&gt;&lt;/div&gt;
&lt;p class="MsoNormal" dir="ltr"&gt;&lt;font face="Courier New" size="2"&gt;Object Plans&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (CACHESTORE_OBJCP)&amp;nbsp;10007&lt;br /&gt;SQL Plans&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (CACHESTORE_SQLCP)&amp;nbsp;10007&lt;br /&gt;Extended Stored Procedures&amp;nbsp;(CACHESTORE_XPROC)&amp;nbsp;127&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" dir="ltr"&gt;&lt;font face="Tahoma"&gt;Respecto a la política para descartar elementos se basa en el espacio de memoria reservado y la reutilización del plan de ejecución.&amp;nbsp;En ningún momento&amp;nbsp;se desprende un trato especial a los procedimientos almacenados. Concretamente en SQL Server 2005 hay ciertas diferencias con la política de caché de SQL Server 2000.&amp;nbsp;Los cachés de planes de&amp;nbsp;ejecución y de datos son distintos. &amp;nbsp;El lazy-writter que decrementa periodicamente el coste de un plan de ejecución (y si es 0 en caso de poca memoria se descarta) en SQL Server 2000 no existe como tal en SQL Server 2005. En vez de eso, cuando las entradas en el caché superan el 50% del tamaño destinado, el siguiente plan que llega al caché decrementa el contador de coste en 1 de todos los anteriores. Realmente este decremento es marcado a lo cerdito (piggybacked) y no es inmediato por el comportamiento, en la práctica,&amp;nbsp;es parecido al del lazy-writter de SQL Server 2000. Cuando el tamaño del caché supera el 75% un hilo con un monitor dedicado se activa y decrementa el coste de los objetos en todas (ojo todas) las cachés. Si el plan se vuelve a utilizar se resetea este contador.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" dir="ltr"&gt;&lt;font face="Tahoma"&gt;&lt;strong&gt;¿Cuándo se invalida el plan de caché, datos etc y se precisa de recompilación?&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;font face="Tahoma"&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;En bastantes circustancias, solo comento las principales (mirar mejor la documentación&amp;nbsp;mencionada)&amp;nbsp;y se agrupan en dos:&lt;/font&gt;&lt;/div&gt;
&lt;blockquote dir="ltr"&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;&lt;strong&gt;A. Razones relativas a la corrección del plan&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;blockquote dir="ltr"&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;font face="tahoma" size="2"&gt;A&lt;/font&gt;&lt;font face="tahoma" size="2"&gt;.1. Modificación en el esquema que afecta a la sentencia (p.e. se borra una tabla)&lt;/font&gt;&lt;/div&gt;
&lt;p dir="ltr"&gt;&lt;font face="tahoma" size="2"&gt;A.2. Llamadas a sp_recompile en un proc. almacenado, logicamente ;-) o que fuese creado con la opción WITH RECOMPILE&lt;/font&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;font face="tahoma" size="2"&gt;A.3. Operaciones que causan la invalidación total del plan de caché, a saber:&amp;nbsp;Hacer un detach. Actualizar una bd (de 2000 a 2005). Ejecutar DBCC FREEPROCCAHE. C&lt;/font&gt;&lt;font face="tahoma" size="2"&gt;omando Reconfigure. Comando ALTER DATABASE ... MODIFY FILE GROUP o COLLATE. &lt;strong&gt;Reiniciar el servidor o el servicio de SQLServer&lt;/strong&gt; también causa la invalidación total de los planes &amp;nbsp;(lo he comprobado)&lt;/font&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;font face="tahoma"&gt;&lt;font size="2"&gt;A.4 Cambios en alguna opción SET antes de la consulta:&lt;font face="Arial"&gt; ANSI_NULL_DFLT_OFF, ANSI_NULL_DFLT_ON, ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, DATEFIRST, DATEFORMAT, FORCEPLAN, LANGUAGE, NO_BROWSETABLE, NUMERIC_ROUNDABORT, QUOTED_IDENTIFIER. Es mejor establecerlos al principio de la conexión o de la sesión o dejárlos fijos en la BD.&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;strong&gt;B. Razones relativas a nivel de optimismo del plan.&lt;/strong&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;font face="arial" size="2"&gt;B.1 Cuando todas las tablas de la consulta están marcadas como de solo lectura el plan no se recompila. &lt;/font&gt;&lt;font face="arial" size="2"&gt;Si la consulta tiene la opción KEEPFIXED tampoco se recompila&amp;nbsp;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="arial" size="2"&gt;B.2. Cuando ciertos indicadores dicen que la consulta ya no es óptima y necesita ser recompilada... depende de bastantes factores como por ejemplo las estádisticas referentes a las tablas implicadas y su tipo (si es variable, temporal, etc.). Para más info verlo en el documento en la sección &amp;quot;Plan optimality.related recompilations: The Big Picture&amp;quot;.&lt;/font&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;font face="arial" size="2"&gt;Evidentemente, aunque no lo incluye el documento queda la opción de que el plan de ejecución sea descartado de la caché por problemas de espacio.&lt;/font&gt;&lt;/p&gt;
&lt;div&gt;&lt;font face="arial" size="4"&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="arial" size="2"&gt;Los planes de ejecución de los Procedimientos Almacenados son creados en la primera invocación de la instancia del servidor SQL Server y son tratados como una entrada más en la caché de planes de ejecución. No parece que haya ninguna ventaja en utilizar procedimientos almacenados en SQL Server 2005&amp;nbsp;para mejorar el rendimiento de consultas preparadas, especialmente en lo que se refiere al caché de&amp;nbsp;planes de ejecución. Por lo que no compensa su creación.&lt;/font&gt;&lt;/div&gt;&lt;/font&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=49951" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="Rendimiento" scheme="http://geeks.ms/blogs/quintas/archive/tags/Rendimiento/default.aspx" /><category term="Procedimientos Alamacenados" scheme="http://geeks.ms/blogs/quintas/archive/tags/Procedimientos+Alamacenados/default.aspx" /><category term="SQL Server" scheme="http://geeks.ms/blogs/quintas/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>Recuperando archivos de imagen de un documento word</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/10/19/recuperando-archivos-de-imagen-de-un-documento-word.aspx" /><id>/blogs/quintas/archive/2007/10/19/recuperando-archivos-de-imagen-de-un-documento-word.aspx</id><published>2007-10-19T11:53:00Z</published><updated>2007-10-19T11:53:00Z</updated><content type="html">&lt;p&gt;Os comento un truquejo, bastante simpático, que os puede ayudar a salir del paso alguna vez.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Problema&lt;/strong&gt;: Me solicitan por separado las imágenes y en su mejor resolución de un documento word&amp;nbsp;donde están incrustadas.&amp;nbsp;No dispongo de los originales (eran capturas de pantalla) pruebo a copiarlas y pegarlas en Photoshop y salen con una calidad lamentable, mucho peor que la del documento.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solución&lt;/strong&gt;: Si el archivo es .docx (Office 2007) podemos hacer lo siguiente: le hacemos una copia (ctrl+c, ctrl+v sobre el archivo) y renombramos la extensión del archivo a .zip. Ojo, quizáis necesitéis ir a una ventana del&amp;nbsp;explorador y en opciones de carpeta desactivar la&amp;nbsp;opción de &amp;quot;Ocultar extensiones de archivos conocidos&amp;quot;. Si examinamos el&amp;nbsp;archivo zip veremos que dentro de la carpeta word\media&amp;nbsp;encontramos&amp;nbsp;las imagenes en formato png, emf, etc.. y a su resolución original.&lt;/p&gt;
&lt;p&gt;Jeje a mi &amp;quot;me salvó la vida&amp;quot;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=43669" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="Word 2007" scheme="http://geeks.ms/blogs/quintas/archive/tags/Word+2007/default.aspx" /><category term="Office 2007" scheme="http://geeks.ms/blogs/quintas/archive/tags/Office+2007/default.aspx" /></entry><entry><title>Parameters.AddWithValue ... with Cuidadito</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/07/13/parameters-addwithvalue-with-cuidadito.aspx" /><id>/blogs/quintas/archive/2007/07/13/parameters-addwithvalue-with-cuidadito.aspx</id><published>2007-07-13T09:00:00Z</published><updated>2007-07-13T09:00:00Z</updated><content type="html">&lt;p&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font face="Calibri" size="3"&gt;Leyendo el hace unos días unos posts muy recomendables del &lt;/font&gt;&lt;a href="http://blogs.msdn.com/sqlprogrammability/archive/2007/01.aspx"&gt;&lt;font face="Calibri" color="#800080" size="3"&gt;Sql Server Programmability &amp;amp; API Development Team Blog&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt; acerca de cómo funciona caché de planes de consultas y procedimientos de &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer 2005&lt;/i&gt;, me enteré de una buena práctica para nuestro código .Net que accede a datos de &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt;. Aunque encuentro lo descubierto más interesante para evitar una mala práctica que, por despiste, seguro que hacemos más de muchos. Y como veremos… me parece que algún chico de &lt;i style="mso-bidi-font-style:normal;"&gt;Redmond&lt;/i&gt; también.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Entremos en vereda...&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Cuando ejecutamos una consulta contra &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt; se emplea un tiempo en crear un plan de ejecución. Ese plan, relativamente costoso de crear, lo almacena en un caché de planes de ejecución. La reutilización de dicho plan mejora considerablemente el rendimiento de &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt; al ahorrarnos un tiempo precioso, y por ende, también mejora el tiempo de respuesta de nuestra aplicación.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Todos estamos más o menos aleccionados a utilizar parámetros en nuestras consultas SQL, sobre todo por razones de seguridad ya que filtra lo pasado a la consulta, evitando ataques por inyección de código SQL. Las consultas parametrizadas son planificadas con sus parámetros, así pueden ser reutilizadas aunque cambie el valor de los parámetros.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Una cosa que me sorprendió es que &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;autoparametriza las consultas que planifica en previsión de que sean reutilizadas:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;SqlCommand command = new SqlCommand(conn);&lt;br /&gt;command.CommandText = &amp;quot;select * from t1 where col1 = 1 and col2 = &amp;#39;abcd&amp;#39;&amp;quot;;&lt;br /&gt;command.ExecuteNonQuery();&lt;br /&gt;command.CommandText = &amp;quot;select * from t1 where col1 = 1 and col2 = &amp;#39;abc&amp;#39;&amp;quot;;&lt;br /&gt;command.ExecuteNonQuery();&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Genera un único plan de ejecución para la consulta:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;(@1 tinyint,@2 varchar(8000))SELECT * FROM [t1] WHERE [col1]=@1 AND [col2]=@2&lt;/span&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Es bastante común ejecutar &lt;span style="mso-ansi-language:ES-TRAD;"&gt;un &lt;i style="mso-bidi-font-style:normal;"&gt;SqlCommand&lt;/i&gt; definiendo los valores de los parámetros y no especificar su tipo, especialmente si utilizamos &lt;i style="mso-bidi-font-style:normal;"&gt;AddWithValue&lt;/i&gt; que ya no nos da opción a definir el tipo del parámetro, muchos desarrolladores lo utilizan porque ahorras una llamada a un método. &lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;Es típico ver esta porción de código&lt;/span&gt;:&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;S&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;qlCommand command = new SqlCommand(&amp;quot;select * from t1 where col1 = @id and col2 = @str&amp;quot;, conn);&lt;br /&gt;command.Parameters.AddWithValue(&amp;quot;@id&amp;quot;, 1);&lt;br /&gt;command.Parameters.AddWithValue(&amp;quot;@str&amp;quot;, &amp;quot;abc&amp;quot;);&lt;br /&gt;command.ExecuteNonQuery();&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;command.Parameters[0].Value = 2;&lt;br /&gt;command.Parameters[1].Value = &amp;quot;abcd&amp;quot;;&lt;br /&gt;command.ExecuteNonQuery();&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;&lt;br /&gt;Examinando el cache de planes de ejecución obtenemos:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-fareast-language:ES;"&gt;(@1 tinyint,@2 nvarchar(3))SELECT * FROM [t1] WHERE [col1]=@1 AND [col2]=@2&lt;br /&gt;(@1 tinyint,@2 nvarchar(4))SELECT * FROM [t1] WHERE [col1]=@1 AND [col2]=@2&lt;/span&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-fareast-language:ES;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-ansi-language:EN;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-fareast-language:ES;"&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Uppps, son dos planes de ejecución distintos. No ha reutilizado la consulta. Se ha perdido un tiempo valioso. &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;Se da la paradoja que la consulta sin parámetros sería más eficaz que la parametrizada en este segundo ejemplo. ¿Por qué ocurre esto? Pues al parecer porque no se ha especificado la longitud del parámetro alfanúmerico y &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt; lo crea como un &lt;i style="mso-bidi-font-style:normal;"&gt;nvarchar&lt;/i&gt; de la longitud del valor pasado. &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;Tranquilos, esto no ocurre con tipos fijos como &lt;i style="mso-bidi-font-style:normal;"&gt;int&lt;/i&gt; o &lt;i style="mso-bidi-font-style:normal;"&gt;datetime&lt;/i&gt;, pero si en nuestra consulta tenemos un parámetro que es un &lt;i style="mso-bidi-font-style:normal;"&gt;string&lt;/i&gt;, &lt;b style="mso-bidi-font-weight:normal;"&gt;evitad utilizar AddWithValue. &lt;/b&gt;&lt;/font&gt;&lt;/font&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;Este otro fragmento de código si sería más correcto:&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;command.CommandText = &amp;quot;select * from t1 where col1 = @id and col2 = @str&amp;quot;;&lt;br /&gt;command.Parameters.Add(&amp;quot;@id&amp;quot;, SqlDbType.Int);&lt;br /&gt;command.Parameters.Add(&amp;quot;@str&amp;quot;, SqlDbType.NVarChar, 50);&lt;br /&gt;command.Parameters[0].Value = 1;&lt;br /&gt;command.Parameters[1].Value = &amp;quot;abc&amp;quot;;&lt;br /&gt;command.ExecuteNonQuery();&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;command.Parameters[0].Value = 2;&lt;br /&gt;command.Parameters[1].Value = &amp;quot;abcd&amp;quot;;&lt;br /&gt;command.ExecuteNonQuery();&lt;/span&gt; &lt;br /&gt;&lt;font face="Calibri" size="3"&gt;&lt;br /&gt;Produciendo un único plan de ejecución:&lt;/font&gt;&lt;span style="FONT-SIZE:8pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-ansi-language:EN-US;"&gt;(@id int,@str nvarchar(50))select * from t1 where col1 = @id and col2 = @str&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri" size="3"&gt;&lt;br /&gt;¿Os imagináis que pasaría si está dentro de un bucle que va insertar masivamente valores en nuestra base de datos? Pues que el caché de planes de ejecución se llenaría de consultas preparadas para cada combinación de parámetros alfanuméricos, sacando otras consultas preparadas (planificadas) del caché de planes de ejecución, además de incurrir en un tiempo extra en planificarla.&lt;/font&gt;&lt;/p&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Lo curioso es que ayer mismo, utilizando un plan de generación de datos en &lt;i style="mso-bidi-font-style:normal;"&gt;VisualStudio 2005 for Database Professionals&lt;/i&gt;,&lt;span style="mso-ansi-language:ES-TRAD;"&gt; &lt;span&gt;descubrí un pequeño detalle al respecto mientras investigaba otra cosa… estaba insertando 524288 tuplas en una tabla de pruebas en la que tenía dos campos con &lt;i style="mso-bidi-font-style:normal;"&gt;NVarChar &lt;/i&gt;(&lt;i style="mso-bidi-font-style:normal;"&gt;psche&lt;/i&gt;… lo hago todos los días antes de desayunar) cuando paralelamente ejecutó una consulta &lt;i style="mso-bidi-font-style:normal;"&gt;Transact-sql&lt;/i&gt; en &lt;i style="mso-bidi-font-style:normal;"&gt;Sql Server Studio Management Express&lt;/i&gt; sobre la tabla del sistema con los planes de ejecución cacheados y me encuentro con esto:&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="mso-no-proof:yes;mso-fareast-language:ES;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;/span&gt; &lt;br /&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;&lt;a href="http://geeks.ms/photos/quintas/images/20502/original.aspx"&gt;&lt;img title="Pantallazo de una consulta ..." style="WIDTH:361px;HEIGHT:480px;" height="480" alt="Pantallazo de una consulta ..." src="http://geeks.ms/photos/quintas/images/20502/640x480.aspx" width="361" align="middle" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Cómo podéis observar en la imagen, ha creado un plan de ejecución por consulta, debido al problema que antes os mencionaba. Probé a hacer un &lt;i style="mso-bidi-font-style:normal;"&gt;count(*)&lt;/i&gt; en la tabla del caché de planes de ejecución y contenía &lt;b style="mso-bidi-font-weight:normal;"&gt;8192&lt;/b&gt; tuplas (oh, curioso límite) con planes de ejecución de esta operación de generación de datos. &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;El impacto de este problema no es excesivamente grave pues los planes de generación de datos se suelen ejecutar en instalaciones de &lt;i style="mso-bidi-font-style:normal;"&gt;SQLServer&lt;/i&gt; en entornos de desarrollo y no en producción, por lo que no parece importante que afecte al rendimiento de otras consultas.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Desde mi punto de vista el problema se encuentra en una mala implementación de &lt;i style="mso-bidi-font-style:normal;"&gt;AddWithValue&lt;/i&gt;, el desarrollador no puede estar pendiente de si un método aparentemente cómodo y eficiente no lo sea, esa es la confianza que depositamos en el .Net Framework. &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Quizás sería recomendable que en futuros &lt;i style="mso-bidi-font-style:normal;"&gt;frameworks&lt;/i&gt; se reescribiera este método sobre todo para que intercepte los tipos de datos alfanuméricos y le ponga un tamaño por defecto al igual que hace &lt;i style="mso-bidi-font-style:normal;"&gt;SqlServer&lt;/i&gt; en las consultas auto parametrizadas. También sería recomendable una sobrecarga de &lt;i style="mso-bidi-font-style:normal;"&gt;AddWithValue&lt;/i&gt; que permita especificar el tipo de dato explícitamente.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=20510" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author><category term="SQL Server 2005" scheme="http://geeks.ms/blogs/quintas/archive/tags/SQL+Server+2005/default.aspx" /><category term=".Net Framework 2.0" scheme="http://geeks.ms/blogs/quintas/archive/tags/.Net+Framework+2.0/default.aspx" /><category term="ADO.Net" scheme="http://geeks.ms/blogs/quintas/archive/tags/ADO.Net/default.aspx" /></entry><entry><title>Service Pack 2 para Windows 2003 Server en español</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/03/27/service-pack-2-para-windows-2003-server-en-espa-ol.aspx" /><id>/blogs/quintas/archive/2007/03/27/service-pack-2-para-windows-2003-server-en-espa-ol.aspx</id><published>2007-03-27T08:14:00Z</published><updated>2007-03-27T08:14:00Z</updated><content type="html">&lt;P&gt;Desde ayer teneis listo para descargar el Service Pack 2 de 2003 server por fin en castellano:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?displaylang=es&amp;amp;FamilyID=1b9fe9e4-1d57-4698-a5cf-db271ed6d90a"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=es&amp;amp;FamilyID=1b9fe9e4-1d57-4698-a5cf-db271ed6d90a&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Oh, si alguno tiene un ISA montado que eche un ojo, por si acaso a:&lt;/P&gt;
&lt;P class=MsoPlainText style="MARGIN:0cm 0cm 0pt;"&gt;&lt;FONT face=arial,helvetica,sans-serif&gt;WARNING! Windows Server 2003 SP2 May Destroy Your ISA Firewall without Warning:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoPlainText style="MARGIN:0cm 0cm 0pt;"&gt;&lt;A href="http://blogs.isaserver.org/shinder/2007/03/23/warning-windows-server-2003-sp2-may-destroy-your-isa-firewall-without-warning/"&gt;&lt;FONT face=arial,helvetica,sans-serif&gt;http://blogs.isaserver.org/shinder/2007/03/23/warning-windows-server-2003-sp2-may-destroy-your-isa-firewall-without-warning/&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoPlainText style="MARGIN:0cm 0cm 0pt;"&gt;&lt;FONT face=arial,helvetica,sans-serif&gt;You cannot host TCP connections when Receive Side Scaling is enabled in Windows Server 2003 with Service Pack 2:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoPlainText style="MARGIN:0cm 0cm 0pt;"&gt;&lt;A href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;927695"&gt;&lt;FONT face=arial,helvetica,sans-serif&gt;http://support.microsoft.com/default.aspx?scid=kb;EN-US;927695&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoPlainText style="MARGIN:0cm 0cm 0pt;"&gt;&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=12347" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Desacoplando System.Web.Cache de nuestra lógica de negocio</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2007/03/26/desacoplando-system-web-cache-de-nuestra-l-gica-de-negocio.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="14747" href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.01.23.15/Source.Samples.Cache.zip" /><id>/blogs/quintas/archive/2007/03/26/desacoplando-system-web-cache-de-nuestra-l-gica-de-negocio.aspx</id><published>2007-03-26T16:22:00Z</published><updated>2007-03-26T16:22:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Normalmente la tarea que más aumenta el tiempo de respuesta en la devolución de una página ASP.NET que consulta contra una BD es la propia consulta a la BD. Un escenario frecuente es la recuperación y presentación de datos con poca tasa de actualización. Para cada cliente que ejecuta la página se ejecuta de nuevo la consulta. Pese a que internamente SQL Server u otro gestor SGBD suele tener planificada las últimas consultas SQL realizadas y dispone de sus propios cachés, no tenemos la certeza de que así sea, sobre todo en momentos de alta carga de consultas, justo cuando más se necesita.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La primera aproximación para mejorar el &lt;/SPAN&gt;&lt;I style="mso-bidi-font-style:normal;"&gt;throughput&lt;/I&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt; contra la BD es hacer las consultas solo en la primera petición de la página, en &lt;I style="mso-bidi-font-style:normal;"&gt;post backs&lt;/I&gt; sucesivos no se realiza la consulta.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:8pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;protected&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load(&lt;SPAN style="COLOR:blue;"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR:#2b91af;"&gt;EventArgs&lt;/SPAN&gt; e)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (!Page.IsPostBack)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;BindData();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:8pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;o:p&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;El método BindData() obtendría los datos de la BD y, por ejemplo, se los asociaría a un &lt;I style="mso-bidi-font-style:normal;"&gt;GridView&lt;/I&gt; , en peticiones posteriores &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;de la página por parte del mismo cliente no se ejecutaría este método, pero se seguirían mostrando los datos en el &lt;I style="mso-bidi-font-style:normal;"&gt;viewstate&lt;/I&gt;. &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;Este codelet significó una gran mejora de ASP.NET 1.0 frente ASP. En ASP.NET 1.0 se introdujo ya un conjunto de clases para gestionar un caché de datos y su política de invalidación. ASP.NET 2.0 mejora y extiende estas características.&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;
&lt;H3 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;FONT size=3&gt;&lt;FONT color=#4f81bd&gt;&lt;FONT face=Cambria&gt;Caché de datos global&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Supongamos&amp;nbsp;un escenario en el que tenemos una serie de datos en la BD relativamente inmutables y que &lt;STRONG&gt;utilizan en común todos los clientes&lt;/STRONG&gt; de nuestra aplicación ASP.NET 2.0. Por ejemplo, una tabla de provincias o de empleados. Con la técnica del apartado anterior, cada vez que un nuevo cliente solicita o recarga la página que contiene un combo con la lista de provincias se ejecuta al menos una consulta contra la BD.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Puesto que los datos son comunes a todos los clientes de la aplicación podemos usar el caché de datos global. Este caché, a menos que se especifique lo contrario, tiene el mismo tiempo de vida y validez que el proceso de nuestra aplicación ASP.NET en el servidor. &lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La afinidad del caché es a nivel de aplicación en un &lt;I style="mso-bidi-font-style:normal;"&gt;pool&lt;/I&gt; de IIS. Por lo que en un entorno de &lt;I style="mso-bidi-font-style:normal;"&gt;webfarming &lt;/I&gt;se tendría un caché global para cada aplicación en un pool dentro de un nodo del clúster. &lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;o:p&gt;
&lt;H3 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;FONT size=3&gt;&lt;FONT color=#4f81bd&gt;&lt;FONT face=Cambria&gt;El caché de ASP.NET en una arquitectura de tres capas&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;En los ejemplos que se pueden encontrar en la documentación de ASP.Net o en los tutoriales de &lt;A href="http://www.asp.net/"&gt;&lt;FONT color=#800080&gt;www.asp.net&lt;/FONT&gt;&lt;/A&gt; se muestran ejemplos del uso del caché con datos en aplicaciones de una sola capa; dentro de una misma página ASP.NET se realizan las consultas a datos, su procesamiento y visualización.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Si bien es práctico en desarrollos de poco alcance, cuando se va a desarrollar una aplicación en un entorno empresarial es muy recomendable una arquitectura en al menos tres capas; Interfaz de usuario (UI), Lógica de Negocio (Business Logic, BL) y acceso a datos (Data Access, DA).&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Si queremos emplear el caché global de datos en nuestra lógica de negocio observaremos que depende realmente de clases del interfaz de usuario pues el objeto Cache se obtiene o bien del objeto Page actual o bien del objeto HttpContext. No podemos usar estas clases en nuestra Lógica de Negocio porque se haría dependiente del interfaz empleado.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;La capa BL debería servirnos para cualquier tipo de interface, WindowsForms, aplicación de consola, etc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Para desacoplar las clases de caché dependientes de ASP.NET de la lógica de negocio, os propongo el siguiente diseño, basado en el patrón de diseño Estrategia (&lt;I style="mso-bidi-font-style:normal;"&gt;Strategy Pattern&lt;/I&gt;) [GAM97] y un patrón Adaptador &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;(wrapper) [GAM97] . Permite elegir varias estrategias de cache y el segundo abstrae el interfaz de System.Web.Caching.Cache .&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;Para el acceso a datos del modelo conceptual se utilizan DataSets en vez de objetos DTO junto a una clase DAO (Direct Access Object) que realiza las consultas al gestor &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;SqlServer.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;El interfaz de usuario (UI) accede a la lógica de negocio a través de una fachada (Facade Pattern)[GAM97] que al carecer de estado es una clase de instancia única (Singleton Pattern)[GAM97]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;IMG title="Diagrama 1. Diagrama estático de clases del ejemplo Sample.TestCache" alt="Diagrama 1. Diagrama estático de clases del ejemplo Sample.TestCache" src="http://geeks.ms/photos/quintas/images/12316/original.aspx"&gt;&lt;/P&gt;
&lt;P class=MsoCaption style="MARGIN:0cm 0cm 10pt;"&gt;&lt;FONT size=2&gt;&lt;FONT color=#4f81bd&gt;&lt;STRONG&gt;Diagrama &lt;SPAN style="mso-no-proof:yes;"&gt;1&lt;/SPAN&gt;. &lt;/STRONG&gt;&lt;SPAN style="FONT-WEIGHT:normal;mso-bidi-font-weight:bold;"&gt;Diagrama estático de clases del ejemplo Sample.TestCache&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La página por defecto invoca con su método BindData() el enlace inicial de los datos a los controles visuales. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; BindData()&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;FacadeData&lt;/SPAN&gt; facade = &lt;SPAN style="COLOR:#2b91af;"&gt;FacadeData&lt;/SPAN&gt;.getWithCacheStrategy();&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;GridView1.DataSource = facade.Employees;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;GridView1.DataBind();&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;En el fragmento de código superior vemos cómo invocando el método getWithCacheSrtategy() se obtiene de forma implícita una instancia de la fachada de acceso a la lógica de negocio y se solicita que utilice una estrategia de caché. La implementación concreta de ICacheStrategy se establece en el fichero web.config.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;appSettings&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;add&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:red;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;key&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;"&lt;SPAN style="COLOR:blue;"&gt;CacheStrategyClass&lt;/SPAN&gt;"&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR:blue;"&gt;Samples.TestCache.CacheStrategyAspNet, Samples.TestCache&lt;/SPAN&gt;"&lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;appSettings&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:8pt;LINE-HEIGHT:115%;mso-ansi-language:ES-TRAD;mso-bidi-font-size:11.0pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La fachada tiene otros dos métodos para obtener una instancia de si misma; &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;getInstance(), que carece de estrategias de cache y getWithCacheStrategy(ICacheStrategy) que acepta desde código una estrategia de cache explícita.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;&lt;o:p&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;FacadeData&lt;/SPAN&gt; getWithCacheStrategy(&lt;SPAN style="COLOR:#2b91af;"&gt;ICacheStrategy&lt;/SPAN&gt; ipd)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (instance == &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;instance = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;FacadeData&lt;/SPAN&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CacheStrategy = ipd;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; instance;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;o:p&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;FacadeData&lt;/SPAN&gt; getWithCacheStrategy()&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; getWithCacheStrategy(getInstanceCacheStrategy());&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;ICacheStrategy&lt;/SPAN&gt; getInstanceCacheStrategy()&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; strCacheStrategyClass =&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;WebConfigurationManager&lt;/SPAN&gt;.AppSettings[&lt;SPAN style="COLOR:#a31515;"&gt;"CacheStrategyClass"&lt;/SPAN&gt;];&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (strCacheStrategyClass != &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR:#2b91af;"&gt;ICacheStrategy&lt;/SPAN&gt;) &lt;SPAN style="COLOR:#2b91af;"&gt;Activator&lt;/SPAN&gt;.CreateInstance(&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;Type&lt;/SPAN&gt;.GetType(strCacheStrategyClass));&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:4pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La fachada también actúa en como proxy a la hora de recuperar los empleados. Se hace bajo demanda y devuelve el &lt;I style="mso-bidi-font-style:normal;"&gt;dataset&lt;/I&gt; del caché en caso de que así se haya configurado o directamente del DAO.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT size=2&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=2&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt; Employees&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;get&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (CacheStrategy != &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (CacheStrategy.getData(&lt;SPAN style="COLOR:#a31515;"&gt;"cachedEmployees"&lt;/SPAN&gt;) == &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CacheStrategy.setData(&lt;SPAN style="COLOR:#a31515;"&gt;"cachedEmployees"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#2b91af;"&gt;EmployeeDAO&lt;/SPAN&gt;.getEmployees())&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt 70.8pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; CacheStrategy.getData(&lt;SPAN style="COLOR:#a31515;"&gt;"cachedEmployees"&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;EmployeeDAO&lt;/SPAN&gt;.getEmployees();&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;El interface de ICacheStra&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;tegy para este ejemplo, es muy sencillo:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;interface&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;ICacheStrategy&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt; getData(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; dataKey);&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; setData(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; dataKey, &lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt; data);&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE:8pt;LINE-HEIGHT:115%;mso-ansi-language:ES-TRAD;mso-bidi-font-size:11.0pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;La implementación para el caso de utilizar el caché de ASP.NET:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt; getData(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; dataKey)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;HttpContext&lt;/SPAN&gt; context = System.Web.&lt;SPAN style="COLOR:#2b91af;"&gt;HttpContext&lt;/SPAN&gt;.Current;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt;) context.Cache[dataKey];&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;o:p&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; setData(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; dataKey, &lt;SPAN style="COLOR:#2b91af;"&gt;DataSet&lt;/SPAN&gt; data)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;HttpContext&lt;/SPAN&gt; context = System.Web.&lt;SPAN style="COLOR:#2b91af;"&gt;HttpContext&lt;/SPAN&gt;.Current;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.Cache.Remove(dataKey);&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.Cache.Add(dataKey, data, &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#2b91af;"&gt;DateTime&lt;/SPAN&gt;.Now.AddMinutes(MIN_TO_EXPIRE),&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:7pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;Cache&lt;/SPAN&gt;.NoSlidingExpiration, &lt;SPAN style="COLOR:#2b91af;"&gt;CacheItemPriority&lt;/SPAN&gt;.Normal, &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:7pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-bidi-font-size:10.0pt;mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;El método &lt;I style="mso-bidi-font-style:normal;"&gt;setData&lt;/I&gt; podría haberse simplificado, sin embargo he preferido esta opción porque, entre otras cosas, se puede controlar el tiempo de invalidación del caché y su prioridad. La clase precisa del contexto HTTP para poder acceder al caché.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Si distribuímos en ensamblados las clases, en el del IU tendríamos las clases Default (página ASPX). En el ensamblado de la lógica de negocio estarían el resto de clases. Nótese que CacheStrategyAspNet tiene una dependencia indirecta a HttpContext.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Este ejemplo podría haberse realizado igualmente con objetos del modelo en vez de con &lt;I style="mso-bidi-font-style:normal;"&gt;DataSets&lt;/I&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Si ejecutamos la aplicación veremos que múltiples peticiones devuelven los mismos datos obtenidos en el mismo instante (columna&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;I style="mso-bidi-font-style:normal;"&gt;RetrievedAt&lt;/I&gt;). Incluso cuando el cliente recarga la página.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;Solo cuando hace clic en “&lt;I style="mso-bidi-font-style:normal;"&gt;Refresh Data&lt;/I&gt;” se actualiza el caché.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;Recordad que este caché es privado a la aplicación en ejecución, se comparte entre todas las sesiones que mantenga la aplicación dentro del pool del&amp;nbsp;servidor IIS, si por ejemplo queréis hacer una consulta con parámetros dependientes de la sesión este esquema no os valdría.&lt;U&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Con este ejemplo hemos visto cómo desacoplar la tecnología de caché de asp.net de una fachada de nuestra lógica de negocio. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:ES-TRAD;"&gt;Queda abierta la discusión para el caso de querer crear un cliente ligero y llevar la lógica de negocio&amp;nbsp;a un servidor distinto al de IIS, usando por ejemplo, Windows Communication Foundation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:10pt 0cm 0pt;"&gt;&lt;SPAN style="mso-ansi-language:EN-US;"&gt;&lt;FONT size=4&gt;&lt;FONT color=#4f81bd&gt;&lt;FONT face=Cambria&gt;Referencias&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;SPAN style="mso-ansi-language:EN-US;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;[GAM97]&lt;SPAN style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Design Patterns, Elements of Reusable Object-Oriented Software, Gamma et Al. &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;Addison-Wesley Eds. 1997. ISBN 0-201-63361-2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/o:p&gt;&lt;/SPAN&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 10pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=12315" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Apple haciendo amigos</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/10/19/Apple-hace-amigos.aspx" /><id>/blogs/quintas/archive/2006/10/19/Apple-hace-amigos.aspx</id><published>2006-10-19T06:53:00Z</published><updated>2006-10-19T06:53:00Z</updated><content type="html">&lt;p&gt;Pues resulta que algunos ipods han salido al mercado (desde apple) con un virus. El virus&amp;nbsp;RavMonE est&amp;aacute; dise&amp;ntilde;ado para S.O. Windows. Apple, textualmente ha dicho:&lt;/p&gt;&lt;p&gt;&amp;quot;As you might imagine, we are upset at Windows for not being more hardy against such viruses, and even more upset with ourselves for not catching it.&amp;quot;&lt;/p&gt;&lt;p&gt;Como puedes imaginarte, estamos enfadados con Windows por no luchar m&amp;aacute;s contra los virus con dureza&amp;nbsp; e incluso estamos m&amp;aacute;s enfadados con nosotros mismos por no haberlo pillado.&lt;/p&gt;&lt;p&gt;Flipante, echando M. sobre Microsoft&amp;nbsp;por no&amp;nbsp;tener un antivirus... si es que le dan a la raz&amp;oacute;n a Ms cuando dice que&amp;nbsp;en&amp;nbsp;Vista va a tener un papel m&amp;aacute;s activo en la tecnolog&amp;iacute;a de antivirus.&lt;/p&gt;&lt;p&gt;Por otra parte... &amp;iquest;qu&amp;eacute; hace apple con un windows para&amp;nbsp;configurar sus ipods? al parecer&amp;nbsp; tiene un contratista que lo usa... eso ha dicho.&lt;/p&gt;&lt;p&gt;Dios me voy corriendo a pasarle AppleAntiVirus a mi ipod, no sea que por usar windows haya pillado el virus. Claro que si me entra no le echar&amp;eacute; a la culpa al hijo *** que hizo el virus, ni a los despistados de PcCillin al que estoy subscrito, ni siquiera a apple por dejar alguna puerta abierta... noooo... la culpa es de microsoft... y de mi sant&amp;iacute;sima madre desde el d&amp;iacute;a que me pari&amp;oacute;. Flipante.&lt;/p&gt;&lt;p&gt;Finalmente, en bastantes blogs la gente est&amp;aacute; responsabilizando a apple y no les parece tampoco muy &amp;eacute;tico echar pestes sobre microsoft, podeis consultarlos en &lt;a href="http://news.com.com/2061-11199_3-6127343.html?part=rss&amp;amp;tag=6127343&amp;amp;subj=news"&gt;http://news.com.com/2061-11199_3-6127343.html?part=rss&amp;amp;tag=6127343&amp;amp;subj=news&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=4855" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Wishlist para Live...</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/10/11/Wishlist-para-Live_2E00__2E00__2E00_.aspx" /><id>/blogs/quintas/archive/2006/10/11/Wishlist-para-Live_2E00__2E00__2E00_.aspx</id><published>2006-10-11T09:47:00Z</published><updated>2006-10-11T09:47:00Z</updated><content type="html">&lt;p&gt;&amp;iexcl;A lo mejor me escuchan!&lt;/p&gt;&lt;p&gt;Bueno, despu&amp;eacute;s de comentar con &lt;a target="_blank" href="http://www.elbruno.com/"&gt;Bruno&lt;/a&gt; las &amp;uacute;ltimas novedades de Live con su &lt;a target="_blank" href="http://geeks.ms/blogs/elbruno/archive/2006/10/10/Prueba-Windows-Live-OneCare-en-Vista.aspx"&gt;OneCare&lt;/a&gt;. Se me ocurre una caracter&amp;iacute;stica que desconozco si ya la tienen en mente pero que a mi y a unos cuantos nos resolver&amp;iacute;a bastantes problemas; os cuento:&lt;/p&gt;&lt;p&gt;Ahora, pr&amp;aacute;cticamente todo el mundo, tiene una conexi&amp;oacute;n a internet permanente en cualquier entorno de trabajo. Por otro lado yo tengo cuatro equipos donde desarrollo mi trabajo / ocio. El del trabajo de la ma&amp;ntilde;ana, el del trabajo de la tarde, el de casa y un portatil que llevo cuando hay &lt;em&gt;fiestas &lt;/em&gt;fuera de casa.&lt;/p&gt;&lt;p&gt;Toda mi informaci&amp;oacute;n y preferencias no ocupan m&amp;aacute;s de 1GB-2GB. Evidentemente no incluyo pel&amp;iacute;culas o m&amp;uacute;sica, simplemente words, c&amp;oacute;digo de proyecto, excel, email, etc. Es bastante com&amp;uacute;n que cuando entro en un ordenador tenga que ir por escritorio remoto a otro para coger los archivos que me hacen falta. No hablemos del correo, que me lo tengo que bajar por pop en 3 outlooks... con id&amp;eacute;nticas reglas y filtrando el correo no deseado por triplicado.&lt;/p&gt;&lt;p&gt;A mi me gustar&amp;iacute;a que mi perfil, con mis datos estuviese en un repositiorio global, que al iniciar sesi&amp;oacute;n en live, se abriera como una carpeta y que autom&amp;aacute;ticamente se cargasen mis preferencias en VisualStudio, Office, y Outlook.&amp;nbsp; Podr&amp;iacute;an tener una tecnolog&amp;iacute;a tipo shadow folders para prevenir ca&amp;iacute;das en la red y mejorar el rendimiento. Evidentemente esto se podr&amp;iacute;a hacer para una intranet con tecnolog&amp;iacute;a actual, pero la realidad es que muchos de nosotros trabajamos en 3 sitios distintos d&amp;oacute;nde no tiene sentido tener la misma intranet. Por otra parte Sharepoint Team Services me arregla algo este problema pero no tiene la soltura y comodidad de lo que acabo de describir.&lt;/p&gt;&lt;p&gt;Es cierto que la mayor&amp;iacute;a de usuarios tendr&amp;iacute;an recelos de que sus archivos est&amp;eacute;n en un disco duro remoto que no controlan, pero es un argumento vac&amp;iacute;o desde que todos env&amp;iacute;amos correo con archivos por hotmail o gmail. Creo que esa desconfianza est&amp;aacute; superada.&lt;/p&gt;&lt;p&gt;Lo dicho a ver si me escuchan... &amp;lt;&amp;lt;suspiro&amp;gt;&amp;gt; ... tendr&amp;iacute;a que despreocuparme de llevar un pen drive o un hd portatil &lt;strong&gt;sincronizado.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=4480" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Tiembla McAfee y Symantec con Vista</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/10/10/Tiembla-McAfee-y-Symantec-con-Vista.aspx" /><id>/blogs/quintas/archive/2006/10/10/Tiembla-McAfee-y-Symantec-con-Vista.aspx</id><published>2006-10-10T16:44:00Z</published><updated>2006-10-10T16:44:00Z</updated><content type="html">&lt;p&gt;Las empresas de antivirus para windows como McAfee, Symantec, etc. est&amp;aacute;n un poco nerviosas con las nuevas caracter&amp;iacute;sticas de seguridad de Windows Vista como el PatchGuard. En el art&amp;iacute;culo, un tanto capcioso, &amp;quot;&lt;a target="_blank" href="http://news.com.com/Why+Microsoft+is+wrong+on+Vista+security/2010-7349_3-6123924.html?tag=pulse.tb"&gt;Why Microsoft is wrong on Vista security&lt;/a&gt;&amp;quot; de George Heron (investigador jefe de mcafee) dice que la confianza en los antivirus se basa en que ha sido gestionada por terceras empresas y Microsoft siempre les dej&amp;oacute; hacer... (les dej&amp;oacute; hacer negocio, vamos) y que eso era una gran ventaja porque as&amp;iacute; proteg&amp;iacute;an tanto a microsoft de sus propios bugs como a los usuarios ;-) pero con el nuevo enfoque de vista con protecciones como PatchGuard (impide hacer hooks a ciertas funciones del API/Kernel) hace que sea muy dificil de implementar antivirus a los &amp;quot;chicos buenos&amp;quot; y que, con lo &amp;quot;ineptos&amp;quot; que son en microsoft con sus &amp;quot;grav&amp;iacute;simos&amp;quot; bugs de seguridad ellos ya no podr&amp;iacute;an hacer nada para que un mont&amp;oacute;n de chicos malos se metieran en nuestros ordenadores por culpa de Ms, claro.&lt;/p&gt;&lt;p&gt;Menuda ret&amp;oacute;rica. Todo para decir que se les acaba el pastel y que a ver si se movilizan los usuarios en contra de Ms para que las bondadosas empresas de antivirus puedan seguir facturando. Sinceramente, que alguien como el Sr. Heron se ponga las s&amp;aacute;banas y haga&amp;nbsp;del fantasma de la inseguridad de los operativos de microsoft solo demuestra lo preocupante de la situaci&amp;oacute;n.&lt;/p&gt;&lt;p&gt;De la misma forma que alg&amp;uacute;n restrasado perteneciente a brigadas de extinci&amp;oacute;n de incendios quem&amp;oacute; el monte para crear la necesidad de contratarlo... deber&amp;iacute;an investigar la relaci&amp;oacute;n de las empresas de antivirus con la aparici&amp;oacute;n de nuevos virus.&lt;/p&gt;&lt;p&gt;Que el colega Heron no nos toque la moral con los fantasmas de siempre. Que se pongan las pilas. Si las&amp;nbsp;multinacionales que fabrican&amp;nbsp;virus y antivirus est&amp;aacute;n nerviosas es que hay algo bueno para los usuarios. Y de quien empiezo a desconfiar seriamente es de McAFee con art&amp;iacute;culos como estos. Habr&amp;aacute; que tenerlos vigilados.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=4436" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Clúster web de applicaciones ASP.NET con Linux Virtual Server e IIS 6.0</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/09/14/Cl_FA00_ster-web-de-applicaciones-ASP.NET-con-Linux-Virtual-Server-e-IIS-6.0.aspx" /><id>/blogs/quintas/archive/2006/09/14/Cl_FA00_ster-web-de-applicaciones-ASP.NET-con-Linux-Virtual-Server-e-IIS-6.0.aspx</id><published>2006-09-14T10:05:00Z</published><updated>2006-09-14T10:05:00Z</updated><content type="html">&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En este post os describo como montar un cluster o web farming de IIS con aplicaciones ASP.NET utilizando como balanceador de carga entre nodos del cl&amp;uacute;ster un &lt;a href="http://www.linuxvirtualserver.org/" target="_blank"&gt;Linux Virtual Server (LVS).&lt;/a&gt; &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Como sabeis, cuando crece el n&amp;uacute;mero de usuarios web el escalado interno de vuestro servidor suele resolver a corto plazo el problema de atender gran numero de peticiones. Pero si teneis &amp;eacute;xito en vuestra web ;-) y empieza a subir exponencialmente el n&amp;uacute;mero de peticiones, vais a tener que buscar otra soluci&amp;oacute;n: el escalado externo. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Las t&amp;eacute;cnicas de &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Computer_cluster" target="_blank"&gt;Clustering&lt;/a&gt; &lt;/em&gt;o &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Web_Farm" target="_blank"&gt;Webfarming&lt;/a&gt; &lt;/em&gt;permiten a&amp;ntilde;adir servidores web o nodos formando un conjunto de m&amp;aacute;quinas que se reparten las peticiones http/https y si una est&amp;aacute; muy cargada o no disponible, otro nodo operativo resuelve la petici&amp;oacute;n. Al final se logran entornos con alta disponibilidad y tolerante a fallos. Para realizar el balanceo de carga puede optarse por soluciones software como LVS o NLBs o por soluciones hardware como conmutadores de capa 7, tambi&amp;eacute;n llamados conmutadores de capa de aplicaci&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;La soluci&amp;oacute;n m&amp;aacute;s &amp;oacute;ptima es la &amp;uacute;ltima pero es much&amp;iacute;simo m&amp;aacute;s cara (entre $30.000 y $60.000). Mediante software se puede montar un balanceo muy econ&amp;oacute;mico (tanto por hardware requerido como por licencias software) utilizando LVS.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Ya puestos en materia los aspectos a considerar son:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt 36pt;text-indent:-21.55pt;"&gt;&lt;font face="verdana,geneva"&gt;&lt;span&gt;&lt;span&gt;1.&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;La instalaci&amp;oacute;n de un Linux con LVS.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt 36pt;text-indent:-21.55pt;"&gt;&lt;font face="verdana,geneva"&gt;&lt;span&gt;&lt;span&gt;2.&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;La configuraci&amp;oacute;n de red y LVS del cl&amp;uacute;ster.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt 36pt;text-indent:-21.55pt;"&gt;&lt;font face="verdana,geneva"&gt;&lt;span&gt;&lt;span&gt;3.&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;La persistencia de la sesi&amp;oacute;n de las aplicaciones web.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Como la mayor&amp;iacute;a de nosotros estamos un poco m&amp;aacute;s acostumbrados a los servidores Windows, ser&amp;eacute; algo m&amp;aacute;s extenso en la configuraci&amp;oacute;n de LINUX y LVS.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Para simular el entorno utilic&amp;eacute; &lt;em&gt;&lt;a href="http://www.vmware.com/" target="_blank"&gt;vmware&lt;/a&gt;&lt;/em&gt; sobre un Debian ya que solo dispon&amp;iacute;a un equipo con 1GB de RAM y necesitaba ejecutar 3 Windows 2003 Server y un LVS.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;strong&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Instalaci&amp;oacute;n de LVS&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Existen bastantes recursos en l&amp;iacute;nea de c&amp;oacute;mo instalar LVS, concretamente yo lo instal&amp;eacute; sobre un Debian con kernel 2.4.7 y la distribuci&amp;oacute;n &lt;a href="http://www.ultramonkey.org/" target="_blank"&gt;UltraMonkey&lt;/a&gt; de LVS. Tambi&amp;eacute;n hay productos comerciales como &lt;a href="http://sourceware.org/piranha/" target="_blank"&gt;Piranha&lt;/a&gt; de RedHat. En el sitio web de UltraMonkey est&amp;aacute; bastante detallado el proceso de instalaci&amp;oacute;n en debian para diversos escenarios.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En esencia, no es muy complicada, pero en mi kernel tuve que compilar e instalar los m&amp;oacute;dulos de IPVS (el core del LVS) manualmente con &lt;em&gt;insmod &lt;/em&gt;y activar el reenv&amp;iacute;o de paquetes ip (&lt;em&gt;packet forwarding)&lt;/em&gt;. Por cierto, tiene tres mecanismos para hacerlo y dependen un poco de la infraestructura de red que tengamos: Rutado directo, encapsulaci&amp;oacute;n IP a IP y NAT. Por comodidad yo eleg&amp;iacute; NAT en mi entorno de vmware.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;IPVS no es simplemente un IP forwarding con un algoritmo de balanceo de carga. IPVS reconstruye los datagramas IP (layer 3) en el mensaje de capa de aplicaci&amp;oacute;n (Layer 4), como por ejemplo mensajes HTTP, y se lo manda completo (en uno o m&amp;aacute;s paquetes IP) al nodo que lo va a resolver. Esto, que parece una tonter&amp;iacute;a, es muy importante porque si no podr&amp;iacute;an llegar peticiones HTTP incompletas y el cl&amp;uacute;ster funcionar&amp;iacute;a intermitentemente. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Aqu&amp;iacute; pod&amp;eacute;is ver el esquema de la red del cl&amp;uacute;ster que mont&amp;eacute;. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="Verdana"&gt;&lt;a href="http://geeks.ms/photos/quintas/picture2485.aspx" target="_blank"&gt;&lt;img border="0" height="71" src="http://geeks.ms/photos/quintas/images/2485/thumb.aspx" width="100" /&gt;&lt;/a&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;font face="Verdana"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;El servidor con LVS se suele llamar Linux Director (LD). El esquema presentado est&amp;aacute; pensado para balanceo de carga con alta disponibilidad. En el caso de precisar tolerancia a fallos en el Linux Director se podr&amp;iacute;a montar un nuevo servidor gemelo y configurarlo seg&amp;uacute;n la documentaci&amp;oacute;n&lt;span&gt;&amp;nbsp; &lt;/span&gt;para que act&amp;uacute;e como respaldo del Linux Director principal.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Fijaos que el LD tiene dos interfaces de red, uno p&amp;uacute;blico de cara al exterior (10.200.11.128) y uno interno para los servidores del cluster (10.200.10.128). Los nodos del cluster (wincluster01 y wincluster02) tienen como puerta de enlace principal la 10.200.10.128, de esta forma las respuestas de los &lt;em&gt;wincluster&lt;/em&gt; llegan al cliente remoto enmascaradas con la ip 10.200.11.128 y no con la IP del nodo del cl&amp;uacute;ster que ha respondido. Esto es imprescindible si estamos manteniendo el seguimiento de la sesi&amp;oacute;n con &lt;em&gt;cookies&lt;/em&gt; (as&amp;iacute; lo hace por defecto ASP.NET) y no queremos que se cree una nueva sesi&amp;oacute;n cuando cambia el nodo que responde. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;El fichero de configuraci&amp;oacute;n del ldirectord es ldirector.cf, ah&amp;iacute; es d&amp;oacute;nde reflejaremos la estructura de nuestro cl&amp;uacute;ster.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;# Global Directives&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;checktimeout=10&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;checkinterval=2&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;autoreload=no&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;quiescent=yes&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;# A sample virtual with a fallback that will override the gobal setting&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;virtual=10.200.11.128:80 &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;real=10.200.10.129:80 masq&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;real=10.200.10.130:80 masq&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;#fallback=127.0.0.1:80 gate&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;service=http&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;request=&amp;quot;/TestCluster&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;receive=&amp;quot;.NET&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;scheduler=rr&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;#persistent=600&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;protocol=tcp&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;checktype=negotiate&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En ese fichero definimos el servidor virtual, 10.200.11.128:80 y los nodos reales (en este caso 2).&lt;span&gt;&amp;nbsp; &lt;/span&gt;Con &lt;em&gt;fallback&lt;/em&gt; podemos definir un servidor de respuesta en caso de que todos los nodos est&amp;eacute;n ca&amp;iacute;dos. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Lo que me result&amp;oacute; curioso fue la forma de comprobar cada dos segundos (&lt;em&gt;CheckInterval=2&lt;/em&gt;) qu&amp;eacute; nodos del cluster est&amp;aacute;n activos. No env&amp;iacute;a un simple ping, en el caso de un servicio http o https hace una petici&amp;oacute;n a una p&amp;aacute;gina de pruebas (&lt;em&gt;request=&amp;quot;/TestCluster&amp;quot;) &lt;/em&gt;y busca una expresi&amp;oacute;n regular en ella &lt;em&gt;(receive=&amp;quot;.NET&amp;quot;). &lt;/em&gt;En caso de no obtener respuesta &lt;em&gt;(checktimeout=10)&lt;/em&gt; o no sea la esperada marca el servidor como ca&amp;iacute;do y manda la petici&amp;oacute;n HTTP a otro lado del cluster. El algoritmo de balanceo para este cl&amp;uacute;ster es RoundRobin (rr), pero hay muchos m&amp;aacute;s. Por ejemplo, si tenemos servidores con distinta capacidad podemos usar Weighted Round Robin (wrr) y darle pesos adecuados (entre 0 y 1) a los nodos. A menor peso, menos peticiones a resolver.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&amp;iquest;Y c&amp;oacute;mo sabemos que todo marcha?, f&amp;aacute;cil, tenemos unas cuantas herramientas para ello. La primera es mirar el &lt;em&gt;syslog&lt;/em&gt; y ver que el deamon ldirectord ha arrancado perfectamente. Luego podemos utilizar ipvsadm, nos informar&amp;aacute; de los nodos definidos, su peso actual (0 - inactivo, 1- activo) y el n&amp;uacute;mero de conexiones activas.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Adem&amp;aacute;s pueden consultarse estad&amp;iacute;sticas que ser&amp;iacute;an representables con software de monitorizaci&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;#ipvsadm &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;IP Virtual Server version 1.0.11 (size=4096)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;Prot LocalAddress:Port Scheduler Flags&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;-&amp;gt; RemoteAddress:Port&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Forward Weight ActiveConn InActConn&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;TCP&lt;span&gt;&amp;nbsp; &lt;/span&gt;10.200.11.128:www rr&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;-&amp;gt; 10.200.10.129:www&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Masq&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;-&amp;gt; 10.200.10.130:www&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Masq&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;#ipvsadm -Ln --stats&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;IP Virtual Server version 1.0.11 (size=4096)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;Prot LocalAddress:Port&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Conns&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;InPkts&lt;span&gt;&amp;nbsp; &lt;/span&gt;OutPkts&lt;span&gt;&amp;nbsp; &lt;/span&gt;InBytes OutBytes&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;-&amp;gt; RemoteAddress:Port&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;TCP&lt;span&gt;&amp;nbsp; &lt;/span&gt;10.200.11.128:80&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;16&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1105&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;536&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;316196&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;732713&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;-&amp;gt; 10.200.10.129:80&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;8&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;690&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;337&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;194315&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;468421&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:8pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;-&amp;gt; 10.200.10.130:80&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;8&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;415&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;199&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;121881&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;264292&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;/font&gt;&lt;/span&gt;&lt;font face="verdana,geneva"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En caso de problemas os recomiendo que utilic&amp;eacute;is tcpdump, aunque no os conozc&amp;aacute;is el protocolo IP al detalle os puede ayudar a resolver problemas en la configuraci&amp;oacute;n de red o de ldirectord.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:12pt;font-family:'Times New Roman','serif';"&gt;&lt;font face="verdana,geneva" size="2"&gt;Una vez que el LD est&amp;aacute; funcionando vamos a configurar los nodos para que puedan ejecutar aplicaciones ASP.NET en el cl&amp;uacute;ster.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/font&gt;&lt;span style="font-size:12pt;font-family:'Times New Roman','serif';"&gt;&lt;font face="verdana,geneva" size="2"&gt;Una vez que el LD est&amp;aacute; funcionando vamos a configurar los nodos para que puedan ejecutar aplicaciones ASP.NET en el cl&amp;uacute;ster.&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;strong&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Persistencia de sesi&amp;oacute;n&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;La sesi&amp;oacute;n de las aplicaciones web contienen el contexto de ejecuci&amp;oacute;n del cliente remoto. Supongo que es un concepto que conocereis todos ;-). &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;La sesi&amp;oacute;n se almacena en la memoria del servidor, el cliente remoto utiliza cookies o par&amp;aacute;metros en el POST para identificarse en el servidor en cada petici&amp;oacute;n y que &amp;eacute;ste sepa asociar los contenidos de una sesi&amp;oacute;n determinada con el cliente correcto.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Lo interesante es que en un cl&amp;uacute;ster hay varios nodos y una petici&amp;oacute;n http puede ser resuelta por cualquier nodo activo del cl&amp;uacute;ster.&amp;nbsp;Si el nodo del cl&amp;uacute;ster no tiene en memoria los datos de la sesi&amp;oacute;n del cliente, porque fue creada en otro nodo, tenemos un problema realmente grave ya que no se puede recuperar el contexto de la aplicaci&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Existen dos enfoques para resolver peticiones http a una aplicaci&amp;oacute;n web dentro de un cl&amp;uacute;ster y no tener el problema mencionado:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;El primer enfoque utiliza afinidad de nodo (&lt;em&gt;sticky sessions, persistent connections...&lt;/em&gt;) en esencia: si un nodo crea una sesi&amp;oacute;n para un cliente, ese nodo resuelve todas las peticiones del cliente remoto para esa sesi&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Es una aproximaci&amp;oacute;n sencilla pero no hay tolerancia a fallos real. Si un nodo se cae, lo hace con las sesiones de sus clientes. Adem&amp;aacute;s si un nodo esta cargado los que hayan iniciado sesi&amp;oacute;n all&amp;iacute; no pueden moverse a otro nodo menos saturado.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En el segundo enfoque cualquier nodo del cl&amp;uacute;ster puede responder la petici&amp;oacute;n. Para eso es necesario que todos los nodos tengan acceso a los datos de las sesiones de los clientes.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Con ASP.NET es posible compartir la sesi&amp;oacute;n de dos formas: en la memoria o en un SqlServer de un servidor al que preguntan los nodos para recuperar una sesi&amp;oacute;n activa.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Esta aproximaci&amp;oacute;n s&amp;iacute; es tolerante a fallos (respecto a los nodos del cl&amp;uacute;ster) y mejora el rendimiento. Aunque hay un punto &amp;uacute;nico de fallo. Para evitarlo ser&amp;iacute;a necesario montar dos SqlServers para mantener la sesi&amp;oacute;n con replicaci&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En mi caso mont&amp;eacute; el gestor de sesiones en memoria dentro de&amp;nbsp;un Server 2003. Basta con iniciar el servicio &amp;quot;Servicio de estado de ASP.NET&amp;quot;. Si bien hay que tocar el registro de windows para indicarle que acepte conexiones remotas y reiniciar el servicio.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Concretamente hay que darle un valor positivo a la clave:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Ah&amp;iacute; tambi&amp;eacute;n pod&amp;eacute;is cambiarle el puerto por defecto, que es el 42424.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Ahora hay que decirle a las aplicaciones ASP.NET d&amp;oacute;nde deben gestionar la sesi&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Para .Net 1.1 hay que tocar el web.config de la aplicaci&amp;oacute;n y modificar la forma de mantener la sesi&amp;oacute;n:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&amp;lt;sessionState &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mode=&amp;quot;StateServer&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;stateConnectionString=&amp;quot;tcpip=10.200.10.131:42424&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="courier new,courier"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;cookieless=&amp;quot;false&amp;quot; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;timeout=&amp;quot;20&amp;quot; &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier 10 Pitch';"&gt;&lt;font face="courier new,courier"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Para probarlo cree una peque&amp;ntilde;a p&amp;aacute;gina .aspx que incrementa una variable de sesi&amp;oacute;n en cada invocaci&amp;oacute;n e informa del nombre de la m&amp;aacute;quina que resuelve la petici&amp;oacute;n junto con el c&amp;oacute;digo de sesi&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Esta aplicaci&amp;oacute;n debe montarse en el mismo directorio virtual de IIS en todos los nodos. En una ejecuci&amp;oacute;n t&amp;iacute;pica y para el entorno descrito podemos obtener resultados como los que siguen.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Petici&amp;oacute;n a http://10.200.11.128/TestCluster&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Postback 1:&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Fecha:&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;/span&gt;13/09/2006 10:19:06&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Servidor:&amp;nbsp;WINCLUSTER01 (10.200.10.129)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Sesi&amp;oacute;n: epeh12552w2blr45u2nhur2e (nueva)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Timeout:&lt;span&gt; &lt;/span&gt;20 min.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Counter (sesi&amp;oacute;n): 1&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Postback 2:&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Fecha:&lt;span&gt;&amp;nbsp;&lt;/span&gt;13/09/2006 10:19:07&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Servidor: WINCLUSTER02 (10.200.10.130)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Sesi&amp;oacute;n: epeh12552w2blr45u2nhur2e (vieja)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Timeout: 20 min.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;"&gt;&lt;font face="verdana,geneva"&gt;Counter (sesi&amp;oacute;n): 2&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;En el primer post se crea una nueva sesi&amp;oacute;n y la crea el nodo WINCLUSTER01. El contador, que se almacena en la sesi&amp;oacute;n, comienza en 1. Se hace una recarga de la p&amp;aacute;gina y el segundo post es contestado por el nodo WINCLUSTER02. Se observa que la sesi&amp;oacute;n es la misma y se ha incrementado el &lt;em&gt;counter&lt;/em&gt; almacenado en la sesi&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Hice varias pruebas tumbando alg&amp;uacute;n nodo del &lt;em&gt;cl&amp;uacute;ster&lt;/em&gt; y no hubo ning&amp;uacute;n problema. En cuanto el servidor Linux Director detecta que un nodo no le devuelve la p&amp;aacute;gina de pruebas le asigna un peso 0, lo descarta y busca otro nodo seg&amp;uacute;n el algoritmo de balanceo. El cliente sufre un retraso de 1 segundo pero recupera el flujo normal de la aplicaci&amp;oacute;n.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="verdana,geneva"&gt;&lt;strong&gt;&lt;span&gt;Conclusiones&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;El aumento de tr&amp;aacute;fico de un sitio web solo puede ser atendido con una soluci&amp;oacute;n basada en &lt;em&gt;cl&amp;uacute;sters&lt;/em&gt;. Lo ideal es garantizar alta disponibilidad y tolerancia a fallos. En este art&amp;iacute;culo se describe una soluci&amp;oacute;n de &lt;em&gt;clustering &lt;/em&gt;para ASP.NET basada en tecnolog&amp;iacute;a heterog&amp;eacute;nea (Linux/OpenSource, Windows/Microsoft). Utilizando Linux/LVS puedes dedicar hardware relativamente antiguo como equipo LinuxDirector y evitarte alguna licencia de 2003 para hacer NLB. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Las ventajas de&amp;nbsp;&lt;em&gt;clustering&lt;/em&gt; son la alta disponibilidad y una tolerancia a fallos total o parcial (dependiendo del esquema elegido y los puntos de fallo &amp;uacute;nicos). Incluso con un n&amp;uacute;mero peque&amp;ntilde;o de usuarios, si la aplicaci&amp;oacute;n es cr&amp;iacute;tica, merece la pena optar por un esquema como el presentado.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Queda para un futuro una prueba de rendimiento de NLB y LVS&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span&gt;&lt;font face="verdana,geneva"&gt;Espero que os haya gustado! y si alguna parte os queda poco clara u oscura coment&amp;aacute;dmelo y ampl&amp;iacute;o el post.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font face="verdana,geneva"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=2484" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Las aplicaciones OpenSource también cascan</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/09/13/Las-aplicaciones-OpenSource-tambi_E900_n-cascan.aspx" /><id>/blogs/quintas/archive/2006/09/13/Las-aplicaciones-OpenSource-tambi_E900_n-cascan.aspx</id><published>2006-09-13T12:37:00Z</published><updated>2006-09-13T12:37:00Z</updated><content type="html">&lt;p&gt;No parece una novedad, pero es que os estaba preparando un post sobre &lt;em&gt;clustering &lt;/em&gt;con LinuxVirtualServer e IIS 6.0 y se me ocurri&amp;oacute; hacerlo con el editor de textos AbiWord.. cuando ten&amp;iacute;a medio art&amp;iacute;culo escrito puls&amp;eacute; no s&amp;eacute; que teclas y me sali&amp;oacute; un error irrecuperable y&amp;nbsp;que si me apetec&amp;iacute;a informar a los programadores. No lo consider&amp;eacute; necesario (no sea que ese proceso se cargase algo m&amp;aacute;s)... perd&amp;iacute; bastante texto... y eso que guarda una copia de seguridad autom&amp;aacute;tica (que ni te informa de que lo ha hecho o te la recupera al abrir de nuevo el programa).&lt;/p&gt;&lt;p&gt;Pues eso, que sigo con el Post... pero que me f&amp;iacute;o m&amp;aacute;s del Word 2007 Beta2.&lt;/p&gt;&lt;p&gt;Chao chiquilines&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=2402" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry><entry><title>Instalando Atlas CTP Julio 2006</title><link rel="alternate" type="text/html" href="/blogs/quintas/archive/2006/08/06/1145.aspx" /><id>/blogs/quintas/archive/2006/08/06/1145.aspx</id><published>2006-08-06T08:49:00Z</published><updated>2006-08-06T08:49:00Z</updated><content type="html">&lt;P&gt;Yo tengo imán para que las instalaciones de CTPs y BETAs casquen. La última es la de Atlas en su CTP de Julio 2006. Al ejecutar ASPNETAtlas.vsi en la instalación se recibe el mensaje de error "La longitud de la cadena no puede ser cero". El resultado final es que no instala&amp;nbsp;/ registra las plantillas de proyecto para VS.2005. Para solucionarlo debeis meter en vuestro registro las dos claves siguientes:&lt;/P&gt;
&lt;P&gt;En:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSEnvCommunityContent\ContentTypes\VSTemplate&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Meteis:&lt;BR&gt;"ClassName"&amp;nbsp;&amp;nbsp;con "VSContentInstaller.VSTemplateInstallerPage" y "DisplayName" con "#VSTemplateContentDisplayName"&lt;/P&gt;
&lt;P&gt;Volveis a ejecutar ASPNETAtlas.vsi que en mi caso anda&amp;nbsp;por la carpeta C:\Archivos de programa\Microsoft ASP.NET\Atlas\v2.0.50727&lt;/P&gt;
&lt;P&gt;Feliz Agosto!&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=1145" width="1" height="1"&gt;</content><author><name>quintas</name><uri>http://geeks.ms/members/quintas/default.aspx</uri></author></entry></feed>
