La verdad es que el tema de la pregeneración de vistas ya es algo sobre lo que he hablado bastante en mi blog, la ultima entrada creo que fué esta referida a temas de rendimiento, algo sobre lo que afecta mucho, sobre todo cuando hablamos de modelos grandes ( en los tiempos de carga y/o de primeras operaciones ). Generalmente, la forma más sencilla de precompilar estas vistas era por medio de una plantilla de T4, como la siguiente, que se encargaba de leer la información de nuestro modelo EDM y generar para esta información un archivo .cs que contenía la pregeneración de vistas y que incluiamos en la compilación de nuestra unidad de trabajo. Si utilizamos Code First, esta plantilla ya no nos servirá ( por lo menos totalmente ) puesto que ya no tenemos un fichero EDMX sobre el que esto trabaje y por lo tanto no tenemos forma de pregenerar estas vistas tan facilmente. Para ayudarnos, el equipo de EF hace un tiempo que saco una herramienta conocida como EF 4.1 Power Tool la cual dispone de una opción para hacernos este trabajo muy sencillo como se puede observar en la siguiente figura, en la que vemos un nuevo menú contextual dentro de Visual Studio con la opción “Optimize Entity Data Model”, opción que automáticamente agregarla un fichero de precompilación de vistas en el proyecto en el que estemos.
Para el que no quiera usar esta herramienta, esta en CTP1 y a muchos no les gusta ( no nos gusta ) instalar betas y demás en nuestros equipos de trabajo real, podemos utilizar el siguiente fragmento de código, para pregenerar las vistas, lógicamente, esta opción es mucho más “manual” que la anterior, pero aunque sea por un mero ejercicio práctico aquí os lo dejo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> EFF4Helper { <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> PregenerateViews<TContext>(TContext context) <span class="kwrd">where</span> TContext : DbContext { <span class="kwrd">using</span> (MemoryStream stream = <span class="kwrd">new</span> MemoryStream()) <span class="kwrd">using</span> (XmlWriter writer = XmlWriter.Create(stream, <span class="kwrd">new</span> XmlWriterSettings() { Encoding = <span class="kwrd">new</span> UTF8Encoding() })) { EdmxWriter.WriteEdmx(context, writer); stream.Seek(0, SeekOrigin.Begin); <span class="kwrd">return</span> GenerateViews(stream); } } <span class="kwrd">static</span> String GenerateViews(Stream edmxContent) { String generatedViews = String.Empty; <span class="kwrd">try</span> { <span class="kwrd">using</span> (StreamWriter writer = <span class="kwrd">new</span> StreamWriter(<span class="kwrd">new</span> MemoryStream())) { XmlReader csdlReader = <span class="kwrd">null</span>; XmlReader mslReader = <span class="kwrd">null</span>; XmlReader ssdlReader = <span class="kwrd">null</span>; GetConceptualMappingAndStorageReaders(edmxContent, <span class="kwrd">out</span> csdlReader, <span class="kwrd">out</span> mslReader, <span class="kwrd">out</span> ssdlReader); EdmItemCollection edmItems = <span class="kwrd">new</span> EdmItemCollection(<span class="kwrd">new</span> XmlReader[] { csdlReader }); StoreItemCollection storeItems = <span class="kwrd">new</span> StoreItemCollection(<span class="kwrd">new</span> XmlReader[] { ssdlReader }); StorageMappingItemCollection mappingItems = <span class="kwrd">new</span> StorageMappingItemCollection(edmItems, storeItems, <span class="kwrd">new</span> XmlReader[] { mslReader }); EntityViewGenerator viewGenerator = <span class="kwrd">new</span> EntityViewGenerator(); viewGenerator.LanguageOption = LanguageOption.GenerateCSharpCode; IList<EdmSchemaError> errors = viewGenerator.GenerateViews(mappingItems, writer); <span class="kwrd">foreach</span> (EdmSchemaError e <span class="kwrd">in</span> errors) { Console.WriteLine(<span class="str">"Error:{0}"</span>, e.ToString()); } MemoryStream memStream = writer.BaseStream <span class="kwrd">as</span> MemoryStream; generatedViews = Encoding.UTF8.GetString(memStream.ToArray()); } } <span class="kwrd">catch</span> (Exception ex) { Console.WriteLine(<span class="str">"Error:{0}"</span>, ex.ToString()); } <span class="kwrd">return</span> generatedViews; } <span class="kwrd">static</span> <span class="kwrd">void</span> GetConceptualMappingAndStorageReaders(Stream edmx, <span class="kwrd">out</span> XmlReader csdlReader, <span class="kwrd">out</span> XmlReader mslReader, <span class="kwrd">out</span> XmlReader ssdlReader) { csdlReader = <span class="kwrd">null</span>; mslReader = <span class="kwrd">null</span>; ssdlReader = <span class="kwrd">null</span>; XNamespace edmxns = <span class="str">"http://schemas.microsoft.com/ado/2008/10/edmx"</span>; XNamespace csdlns = <span class="str">"http://schemas.microsoft.com/ado/2008/09/edm"</span>; XNamespace mslns = <span class="str">"http://schemas.microsoft.com/ado/2008/09/mapping/cs"</span>; XNamespace ssdlns = <span class="str">"http://schemas.microsoft.com/ado/2009/02/edm/ssdl"</span>; XDocument edmxDoc = XDocument.Load(edmx); <span class="kwrd">if</span> (edmxDoc != <span class="kwrd">null</span>) { XElement edmxNode = edmxDoc.Element(edmxns + <span class="str">"Edmx"</span>); <span class="kwrd">if</span> (edmxNode != <span class="kwrd">null</span>) { XElement runtimeNode = edmxNode.Element(edmxns + <span class="str">"Runtime"</span>); <span class="kwrd">if</span> (runtimeNode != <span class="kwrd">null</span>) { <span class="rem">// Create XmlReader over CSDL in EDMX</span> XElement conceptualModelsNode = runtimeNode.Element(edmxns + <span class="str">"ConceptualModels"</span>); <span class="kwrd">if</span> (conceptualModelsNode != <span class="kwrd">null</span>) { XElement csdlContent = conceptualModelsNode.Element(csdlns + <span class="str">"Schema"</span>); <span class="kwrd">if</span> (csdlContent != <span class="kwrd">null</span>) { csdlReader = csdlContent.CreateReader(); } } <span class="rem">// Create XmlReader over MSL in EDMX</span> XElement mappingsNode = runtimeNode.Element(edmxns + <span class="str">"Mappings"</span>); <span class="kwrd">if</span> (mappingsNode != <span class="kwrd">null</span>) { XElement mslContent = mappingsNode.Element(mslns + <span class="str">"Mapping"</span>); <span class="kwrd">if</span> (mslContent != <span class="kwrd">null</span>) { mslReader = mslContent.CreateReader(); } } <span class="rem">// Create XmlReader over SSDL in EDMX</span> XElement storageModelsNode = runtimeNode.Element(edmxns + <span class="str">"StorageModels"</span>); <span class="kwrd">if</span> (storageModelsNode != <span class="kwrd">null</span>) { XElement ssdlContent = storageModelsNode.Element(ssdlns + <span class="str">"Schema"</span>); <span class="kwrd">if</span> (ssdlContent != <span class="kwrd">null</span>) { ssdlReader = ssdlContent.CreateReader(); } } } } } } } |
1 |
|
Saludos
Unai
Siempre que veo un post de EF deduzco que es tuyo y automaticamente se me alegra el dia sabiendo que voy a aprender algo nuevo. Genial post, como siempre. Saludos desde Redmond!