Jornada de Acceso a Datos en el MUG

por Daniel Laco  22. agosto 2011

El 31 de Agosto estaré participando de una jornada completa sobre temas de Acceso a Datos.

Se desarrollará desde las 9 hasta las 18 en la UADE (Univ. Argentina de la Empresa). 

Salón Auditorio - Lima 717, puerta M, Ciudad de Buenos Aires

En evento está referido a tecnologías, herramientas y técnicas sobre el manejo de datos en programación. Se verán temas como ORM, NoSql, La Nube, etc.

Se pueden registrar aquí

 

HorarioTemaOrador
09:00Keynote – Apertura del eventoMartín Salías
09:10Preview de SQL Server 2011 (Denali)Maxi Acotto
10:10SQL AzureGuadalupe Casuso
11:00Coffee break
11:20¿Por Qué Entity Framework?Daniel Laco
12:10Mobile Data AccessCarlos Perez
13:00Almuerzo Libre
15:20oData / Web APIPablo Cibraro
15:20Web Storage en HTML5Rodolfo Finochietti
16:10Coffee break
16:20Bases de datos NoSQLJohnny Halife
17:10Persistencia con NHibernate 3.2.0Fabio Maulo
18:00Cierre

Nos vemos en el evento !

 

Tags: , ,

ADO.NET | Entity Framework

Video: Run Web Camp Buenos Aires

por Alejandra Federico  10. mayo 2011

A mediados de Marzo participó Daniel Laco junto a Martin Salías como orador en una de las conferencias del evento sobre web que organizó Microsoft, donde contaron con la presencia de dos invitados "oficiales", Phil Haack (Program Manager de ASP.NET MVC) y Drew Robbins (Technical Evangelist).

Les dejo el video de Acceso a datos con Entity Framework, con Daniel Laco y Martín Salías. 

 

Pueden encontrar el resto de las charlas Aquí.

Tags: ,

ASP.NET | Entity Framework

Run Web Camp en Córdoba

por Alejandra Federico  5. mayo 2011

El lunes 16 de Mayo estará participando Daniel Laco (MVP) junto a Eugenio Serrano (MVP) y Enrique Dutra (MVP) en una de las conferencias sobre web que realiza Microsoft, con el impulso del MUG y con el apoyo del Departamento de Ingeniería de Sistemas de UTN Facultad Regional Córdoba.

Lugar: Aula Magna UTN, Maestro M. Lopez esq. Cruz Roja Argentina Ciudad Universitaria - Córdoba Capital. 

Horario: 17:00 a 22.00 Hs.

Agenda: 

17:00 Acreditación.
17:30 Apertura del evento, presentación de los oradores, explicación del contenido de software que se entregará a los asistentes.
17:40 Acceso a Datos y Modelado con Entity Framework (Daniel Laco)
19:00 Intervalo.
19:20

Seguridad en la nube. Gestión con BRS Datacenter. Demos con máquinas virtuales (Enrique Dutra)

20:40 ASP.Net MVC. Un cambio de vista en MVC: Razor Syntax. Aplicaciones Ajax con MVC  (Eugenio Serrano)
22.00 Cierre

Más información AQUÍ

Registración AQUÍ

Tags:

ASP.NET | Desarrollo Web | Entity Framework

Ejemplos y Presentación del Run WebCamp – Acceso a Datos y Modelado con Entity Framework

por Daniel Laco  15. marzo 2011

 

Yá están publicados los ejemplos y la presentación de la charla que realizamos en el evento Run WebCamp con el compañero de ruta, Martín Salías.

Pueden encontrar los archivos en www.vemn.com.ar/conferencias

 

Tags: , , ,

ASP.NET | Entity Framework | General | Sharepoint

Run Web Camp en Buenos Aires

por Daniel Laco  1. marzo 2011

El 15 de Marzo estaré participando junto a Martin Salías como orador en una de las conferencias del evento sobre web que organiza Microsoft.

En esta oportunidad estaremos hablando de Acceso a Datos y Modelado con Entity Framework, siempre dentro del ambiente de ASP.NET MVC.

En http://www.microsoft.com/argentina/run/ pueden encontrar toda la agenda y el link de registración.

Es una jornada muy interesante porque contaremos con la visita de Phil Haack, Program Manager de ASP.NET

Tags: ,

ASP.NET | Desarrollo Web | Entity Framework

Como obtener el Connection String clásico con Entity Framework

por Andres Stang  28. enero 2011

Como sabrán Entity Framework utiliza un conection string para saber con qué base de datos trabajar, el tema es que además de contener la cadena de conexión que conocemos de toda la vida, tiene un poco más de información que utiliza para indicarle otras cosas que no vienen al caso.

Si quisiéramos recuperar la clásica cadena de conexión para, por ejemplo, no utilizar Entity Framework y acceder directamente a la base de datos con ADO.NET uno pensaria en hacer:

 

   1:  MiModeloEntities miEntities = new MiModeloEntities();
   2:  string connStringEF = miEntities.Connection.ConnectionString;

 

Pero no nos serviría! Ya que tenemos la cadena de conexión de Entity Framework que incluye metadata que antes mencionamos. Ya sé, seguramente ya estás pensando en usar expresiones regulares… Momento! La solución? Simplemente:

 

   1:  MiModeloEntities miEntities = new MiModeloEntities();
   2:  string connString = ((System.Data.EntityClient.EntityConnection)miEntities.Connection).StoreConnection.ConnectionString;

 

Y de esta manera nos evitamos tener duplicada la información en nuestra configuración y evitamos parsear el string innecesariamente.

Tags: ,

.NET | Entity Framework | ORM | SQL Server

Self-Tracking Entities en Entity Framework 4

por emmanuel  24. agosto 2010

Introducción: tipos de entidades en Entity Framework

Desde la salida de Entity Framework, al generar modelos de entidades, las clases generadas derivan de EntityObject.
Con la salida de la versión 4 de Entity Framework, se incorpora soporte para seleccionar el tipo de entidad de la cual van a derivar nuestras entidades de negocio: a los clásicos EntityObject se agregan como novedad POCO, POCO Proxies y Self-Tracking entities.
Antes de desarrollar las entidades de tipo Self-Tracking (el objetivo de este artículo), es conveniente dar un panorama de estos diferentes tipos de entidades, para poder decidir cual utilizar, dependiendo de la arquitectura de la aplicación a realizar:

  • EntityObject

Por defecto, las herramientas de ADO.NET Entity Data Model generan tipos de entidades que derivan de EntityObject. En este caso, el ObjectContext administra las relaciones entre los objetos, mantiene el historial de los cambios que ocurren (Change-Tracking) y soporta Lazy Loading.

Sin embargo, este tipo de entidades dependen fuertemente del Entity Framework. Si se desea trabajar con arquitecturas que no conocen la forma de persistencia (por ejemplo: TDD, Test-Driven Development), lo más deseable es utilizar entidades de tipo POCO o POCO Proxy.

  • POCO

Entity Framework permite utilizar objetos del dominio existentes junto con el modelo de datos, sin hacer cambios a las clases de datos. Estas clases POCO ("Plain-Old" CLR Objects), son conocidas como objetos que ignoran la persistencia y soportan las mismas funcionalidades de Query, Insert, Update y Delete que los objetos EntityObject.

Al trabajar con entidades POCO, los cambios que se realicen al grafo de objetos no son mantenidos automáticamente por Entity Framework a medida que ocurren, sino que se utiliza un mecanismo de snapshots para detectarlos: se debe llamar a DetectChanges para sincronizar el ObjectContext con el grafo actualizado (por defecto, el ObjectContext llama a este método antes de grabar los datos).

Este mecanismo utiliza mas memoria que el anterior y puede afectar la performance, especialmente si la aplicación requiere la detección de cambios frecuentemente. Para poder tener una notificación instantánea de los cambios, se debe activar la creación de objetos Change-Tracking Proxy, y para activar Lazy Loading se debe activar la creación de Proxies de Lazy Loading.

  • POCO Proxy

Se debe utilizar en los casos en los que se requiera detección de cambios instantánea y Lazy Loading. Al utilizarlo, se tiene la misma funcionalidad que con entidades tipo EntityObject, pero con las clases del dominio separadas del Entity Framework. Los proxies se crean en tiempo de ejecución, lo que implica que las entidades generadas difieren del tipo POCO, introduciendo algunas complicaciones con la serialización. Por otra parte, la creación de proxies consume mas recursos que los objetos POCO.

  • Self-Tracking Entities

Los tres tipos definidos anteriormente funcionan correctamente en aplicaciones donde los objetos pueden ser agregados (Attach) al ObjectContext que maneja el historial de cambios. Sin embargo, cuando se desea transferir un grafo de entidades a una capa donde el ObjectContext no está disponible, se debe decidir como mantener el historial de cambios y reportar esos cambios de vuelta al ObjectContext (por ejemplo: arquitectura en capas, ambientes desconectados, arquitecturas SOA, etc.).

A partir de la versión 4 de Entity Framework, las entidades del tipo Self-Tracking pueden grabar cambios a las propiedades escalares, complejas o de navegación. Este tipo de entidades no dependen del Entity Framework, y son generadas con el template de ADO.NET Self-Tracking Entity Generator.

Self-Tracking Entities

En arquitecturas en capas, el ObjectContext puede no estar disponible en la capa que modifica las entidades. A partir de Visual Studio 2010 (con Entity Framework 4), está disponible el template ADO.NET Self-Tracking Entity Generator. Este template genera dos archivos .tt (text template):

El archivo <nombreModelo>.tt genera los tipos de entidades y una clase helper que contiene la lógica de mantenimiento de cambios, mas los métodos de extensión que permiten establecer el estado de las entidades.

El archivo <nombreModelo>.Context.tt genera un ObjectContext tipado y una clase de extensión que contiene los métodos ApplyChanges para las clases ObjectContext y ObjectSet. Estos métodos examinan la información del historial de cambios para inferir las operaciones a realizar para grabar los cambios en la base de datos.

Para acceder al template se debe hacer click derecho sobre la superficie del diseñador de entidades, y seleccionar “Add Code Generation Item”:

SelfTracking001

 

En la ventana que aparece, seleccionar “ADO.NET Self-Tracking Entity Generator”:

SelfTracking002

Al presionar “Add”, se ejecutarán los templates que crearán las clases necesarias, las cuales contendrán los métodos de extensión necesarios para trabajar con Self-Tracking:

SelfTracking003

Métodos de extensión de Self-Tracking Entities

  • StartTracking

Este método se utiliza para comenzar el Change-Tracking (rastrear cualquier cambio que ocurra en la entidad). Esto incluye propiedades escalares, colecciones y referencias a otras entidades. Las entidades de tipo Self-Tracking inician el Change-Tracking automáticamente cuando son deserializadas en un cliente a través de WCF. También se activa para nuevas entidades creadas en los siguientes escenarios:

  1. Una relación es creada entre la nueva entidad y una entidad que actualmente tiene Change-Tracking activado.
  2. Se llama al método MarkAs o AcceptChanges en una entidad.

 

  • StopTracking

Este método finaliza el Change-Tracking en una entidad.

  • MarkAs

Todos los métodos que comienzan con “MarkAs” activan el Change-Tracking. Estos métodos permiten cambiar el estado de una entidad a Added, Modified, Deleted, o Unchanged, y además retornan la misma entidad a la cual son aplicados, con el estado modificado:

MarkAsAdded cambia el estado de una entidad a Added. Las nuevas entidades Self-Tracking son creadas en este estado y con Change-Tracking desactivado.

MarkAsDeleted cambia el estado de una entidad a Deleted.

MarkAsModified cambia el estado de una entidad a Modified. Este estado también se obtiene al cambiar el valor de una propiedad en una entidad con Change-Tracking activado.

MarkAsUnchanged cambia el estado de una entidad a Unchanged. También se obtiene este estado al llamar al método AcceptChanges.

  • AcceptChanges

Este método elimina la información de Change-Tracking para una entidad y coloca el estado en Unchanged (es decir, la entidad acepta los cambios que se le realizaron).

Métodos de extensión de ObjectContext

  • ApplyChanges

Examina la información del historial de cambios contenida en el grafo de entidades e infiere el conjunto de operaciones que deben realizarse para reflejar los cambios en la base de datos. Hay dos métodos ApplyChanges, uno para el ObjectContext y otro para el ObjectSet.

Consideraciones para trabajar con entidades Self-Tracking

Finalmente, para cerrar, les dejo algunas consideraciones a tener muy en cuenta antes de utilizar este tipo de entidades:

  • Al enviar un grafo modificado a un servicio, y luego intentar continuar trabajando con el el grafo modificado en el cliente, se debe iterar manualmente por el grafo en el cliente y llamar a AcceptChanges en cada objeto para resetear el Change-Tracking.

  • Las entidades Self-Tracking no permiten realizar Lazy Loading.

  • La serialización Binaria y la serialización a objetos de administración de estados ASP.NET no es soportada por el código generado por los templates de ADO.NET Self-Tracking Entity Generator, para soportala se debe agregar el código necesario al template.

Fuentes:

Tags: ,

ADO.NET | Entity Framework | Visual Studio

A pensar en paralelización: Parallel Extensions

por Gustavo Lombardo  29. julio 2010

Si deseamos que nuestro software siga beneficiándose de las capacidades futuras de hoy y mañana de los procesadores debemos empezar a cambiar nuestra manera de desarrollar. La razón de esto es que las aplicaciones de negocio van tener que ejecutarse en máquinas multi-core o con varios procesadores. Hasta hace pocos años una máquina con varios procesadores estaba prácticamente reservada a la supercomputación, pero hoy en día ya son comunes en cualquier PC de escritorio.

La programación concurrente y el paralelismo no son una materia trivial, la sincronización entre procesos no lo es y dividir el trabajo, asignarlo a varios procesadores, recoger los resultados y mezclarlos para reconstruir la solución final tampoco.

En el pasado, la paralelización requería manipulación de bajo nivel de los subprocesos y bloqueos. Hoy en día, los desarrolladores no tendrían que luchar contra esta complejidad, porque sería dar un paso atrás en productividad. Su tarea es seguir dedicando sus esfuerzos a lo que mejor saben hacer que es desarrollar aplicaciones de alto nivel que resuelven problemas de negocio sin controlar la ejecución concurrente de sus procesos.

Para ello, debemos acostumbrarnos a usar el término task en lugar del thread como seguramente la mayoría de nosotros veníamos haciendo y aprovechar las nuevas capacidades que ofrece las APIs de .NET Framework 4, así como también las del Visual Studio 2010.

.NET Framework 4, proporciona un nuevo runtime, nuevos tipos de biblioteca de clases y nuevas herramientas de diagnóstico para la programación paralela y concurrente. Es aquí donde hace su aparición Parallel Extensions, simplificando el desarrollo en paralelo, de modo de poder escribir código paralelo eficaz, específico y escalable de forma natural sin tener que trabajar directamente con subprocesos. Sin embargo, no todo código se presta para la paralelización por ejemplo, si un bucle realiza solo una cantidad reducida de trabajo en cada iteración o no se ejecuta para un gran número de iteraciones, la sobrecarga de la paralelización puede dar lugar a una ejecución más lenta del código. Además, al igual que cualquier código multiproceso, la paralelización hace que la ejecución del programa sea más compleja.

Parallel Extensions se compone de dos partes: Parallel Linq (PLINQ) y Task Parallel Library (TPL). También consta de un conjunto de estructuras de datos de coordinación (CDS) utilizada para sincronizar y coordinar la ejecución de tareas concurrentes. La siguiente ilustración proporciona información general de alto nivel de la arquitectura de programación paralela en .NET Framework 4.

IC389193

A continuación explicaré cada uno de sus componentes. PLINQ implementa el conjunto completo de operadores de consulta estándar de LINQ  e incluye otros adicionales para las operaciones paralelas. Combina la simplicidad y legibilidad de la sintaxis de LINQ con la eficacia de la programación paralela. En muchos escenarios, PLINQ puede aumentar significativamente la velocidad de las consultas LINQ  to Objects utilizando todos los núcleos disponibles en el equipo host de una forma más eficaz. Para hacer esto divide el origen de datos en segmentos y, a continuación, ejecuta la consulta en cada segmento en subprocesos de trabajo independientes en paralelo en varios procesadores. La clase System.Linq.ParallelEnumerable expone casi toda la funcionalidad de PLINQ.  Les mostraré un ejemplo en el que invoco el método de extensión ParallelEnumerableAsParallel() para indicarle que la query debe ejecutarse en forma paralela.

for (var i = 0; i < data.Length; i++)
{
    data[i] = i;
}
 
data[1000] = -1;
data[14000] = -2;
data[15000] = -3;
data[676000] = -4;
data[8024540] = -5;
data[9908000] = -6;
 
var negativos = from valor in data.AsParallel()
                where valor < 0
                select valor;

 

Al ejecutarse la query en paralelo los resultados de cada subproceso de trabajo deben volver a combinarse en el subproceso principal por ejemplo para la inserción en una lista. El tipo de combinación que  PLINQ realiza depende de los operadores que se encuentran en la consulta. Con el método WithParallelMergeOptions(), puede indicarse a PLINQ una sugerencia de que tipo de combinación se va a realizar.

La biblioteca TPL es un conjunto de API que tiene como propósito lograr que los desarrolladores aumenten la productividad simplificando el proceso de agregar paralelismo y simultaneidad a las aplicaciones, utilizando eficazmente todos los procesadores que están disponibles. Además, se encarga de la división del trabajo, la programación de los subprocesos y otros detalles de bajo nivel.

El concepto principal de Parallel Extensions es una tarea, que es una pequeña unidad de código, de forma independiente. Se encarga de dividir el trabajo y lanzar un número óptimo de threads basándose en el número de CPUs o cores que tenemos.

Yendo aun mas allá, sin llegar al nivel de granularidad de una task, podemos trabajar a más alto nivel aún con la clase estática Parallel y escribir código como el siguiente:

static void Main()
{
    Parallel.For(from, to, i=> )
    {
    });
}
 

Mediante un ciclo como el anterior, dejamos que el runtime de Parallel Extensions se encargue de paralelizar el trabajo creando las tasks y encargándose de  todo el proceso. A continuación les mostraré las mejoras de rendimiento al paralelizar un programa muy sencillo. El método SumaRaicesNesimaDeX devuelve la suma de las raíces n-énesima de todos los enteros entre 1 y un 10 millones donde n es una variable recibida como parámetro. La forma de resolución de la raíz contiene pasos de procesamiento adicionales que aumentan el tiempo de ejecución total de la consulta. Además, en el main utilizo la clase Stopwatch para determinar cuantos milisegundos tarda el programa en ejecutarse.

static void Main()
{
    var tiempo = Stopwatch.StartNew();
    
    for (var i = 2; i < 20; i++)
    {
        var resultado = SumaRaicesNesimaDeX(i);
        Console.WriteLine("Raiz {0} = {1} ", i, resultado);
    }
 
    Console.WriteLine(tiempo.ElapsedMilliseconds);
    Console.ReadLine();
}
 
public static double SumaRaicesNesimaDeX(int n)
{
    double resultado = 0;
 
    for (var x = 1; x < 10000000; x++)
    {
        //Raíz n-ésima de x
        resultado += Math.Exp(Math.Log(x) / n);
    }
 
    return resultado;
}
 

El programa lo ejecute en AMD Phenom II X4 810 de 64 bits con 4 GB de memoria RAM y tardó aproximadamente 16 segundos.

Ahora si remplazo el ciclo:

for (var i = 2; i < 20; i++)
{
    var resultado = SumaRaicesNesimaDeX(i);
    Console.WriteLine("Raiz {0} = {1} ", i, resultado);
}

 

por el siguiente código añadiéndole paralelismo:

Parallel.For(2, 20, (i) =>
{
    var resultado = SumaRaicesNesimaDeX(i);
    Console.WriteLine("Raiz {0} = {1} ", i, resultado);
});

Mediante pequeñas modificaciones del código como son un índice de inicio y de fin y la llamada a través de un delegate, la ejecución del programa solo tarda aproximadamente 4 segundos y medio.

Visual Studio 2010 incluye nuevas herramientas de profiling y debugging para la ejecución concurrente. Un ejemplo de esto es el visualizador de concurrencia. Esta herramienta ayuda  a analizar nuestras aplicaciones secuenciales para descubrir las oportunidades de paralelismo. El visualizador de concurrencia incluye visualización y herramientas de reporte. Hay tres puntos de vista principales: utilización de CPU, subprocesos y núcleos.

imageEl eje X muestra el tiempo transcurrido desde el inicio de la traza hasta el final de la actividad de la aplicación. El eje Y muestra el número de núcleos de procesadores lógicos en el sistema. La zona verde representa el número medio de cores lógicos que se analiza en la aplicación en un momento dado en la ejecución del profiling. El resto de los núcleos por otros procesos que se ejecutan en el sistema (que se muestra en amarillo).

Si queremos paralelizar nuestra aplicación, debemos buscar áreas de ejecución que presentan largas regiones verdes a nivel de un solo núcleo en el eje Y o regiones donde no hay mucha utilización de la CPU, donde el verde no demuestra ni es considerablemente menos de 1 en promedio. Ambas circunstancias podrían indicar una oportunidad para la paralelización. En segundo lugar, si estamos tratando de afinar la aplicación paralela, esta vista le permite confirmar el grado de paralelismo que existe cuando la aplicación se ejecuta.

Este cambio de paradigma nos exige una nueva manera de pensar. Los threads son una abstracción demasiado débil. Debemos empezar a pensar en tareas no en threads y en relaciones entre esas tareas y su concurrencia en lugar de sincronización de threads. Seremos los desarrolladores quienes de un modo u otro tendremos que empezar a pensar en paralelización.

Tags:

.NET | Entity Framework | Visual Studio

Lanzamiento Virtual “La eficiencia en tus manos”

por Daniel Laco  16. abril 2010

Hola a todos, quiero recordarles que este 21 de Abril será el evento virtual de lanzamiento de 11 importantes productos y donde muchos MVPs estaran como speakers y como expertos para resolver tus dudas.

clip_image003_010b7c0b-5450-4bae-8599-79e3ef3ca26b

 clip_image001_0d130959-9982-4736-8319-5fff7ce34ca4

 

 

clip_image002_f403aaf7-c2c3-4e8d-beb7-f7bb8c027891

Regístrate ya!

Tags:

.NET | ASP.NET | Entity Framework | General | Sharepoint | Visual Studio

Cuál es la mejor forma de realizar procesos batch con Entity Framework?

por Daniel Laco  16. abril 2010

Es muy común que en las aplicaciones sea necesario realizar procesos de actualizaciones masivas. Siempre está la tentación de usar EF para hacer estos procesos, ya que es muy fácil buscar y actualizar registros. Pero en el caso de EF el costo que se paga por toda la infraestructura que tiene es muy alto.

En el caso de procesos masivos, si hay que actualizar o borrar un registro, primero hay que traerlo (esto implica que EF mantenga el tracking con el ObjectStateManager) posteriormente hacer la actualización o borrado y por último realizar la actualización con el ObjectContext.

Resumiento, para realizar procesos batch lo mejor es NO USAR Entity Framework !!

Pero que opciones tengo entonces?

Voy a mostrar 2 alternativas de las muchas que hay, simulando que hay que leer un archivo .TXT de longitud fija  y posteriormente hay que realizar una actualización de miles de registros en una tabla de la base de datos.

El escenario es que recibo un archivo con códigos de productos de la empresa y códigos de productos de proveedores externos. El proceso que hay que realizar es: leer el archivo y actualizar los códigos de de los proveedores externos en cada registro de los productos de la empresa.

Para esto usaremos como ayuda la excelente libreria FileHelpers realizada por Marcos Meli

El formato en que viene el archivo es el siguiente:

 

/// <summary>
/// Archivo de Unión de Códigos de Productos de la Empresa y Proveedores
/// </summary>
 
[FixedLengthRecord(FixedMode.AllowLessChars)]
public class UnionProductos
{
    [FieldFixedLength(7)]
    public int EmpresaCodigo;
 
    [FieldFixedLength(7)]
    public string Proveedor1Codigo;
 
    [FieldFixedLength(7)]
    public int Proveedor2Codigo;
 
}

 

El proceso de lectura con FileHelpers:

FileHelperEngine engine = new FileHelperEngine(typeof(UnionProductos));
UnionProductos[] UnionLeido = engine.ReadFile(nombreArchivo) as UnionProductos[];
 
 

Opción 1

Recorrer el array de Productos y ejecutar un Store Procedure con la actualización correspondiente:

 

string stringDeConexion = "XXXXXXXXXXXXXXXX";
using (SqlConnection conn = new SqlConnection(stringDeConexion))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand("nombreStore", conn);
    cmd.Parameters.Add("@empresaCodigo", SqlDbType.Int);
    cmd.Parameters.Add("@proveedor1Codigo", SqlDbType.VarChar);
    cmd.Parameters.Add("@proveedor2Codigo", SqlDbType.Int);
 
 
    foreach (UnionProductos producto in UnionLeido)
    {
        cmd.Parameters[0].Value = producto.EmpresaCodigo;
        cmd.Parameters[1].Value = producto.Proveedor1Codigo;
        cmd.Parameters[2].Value = producto.Proveedor2Codigo;
 
        cmd.ExecuteNonQuery();
 
    }
}

 

Por supuesto el Store hace algo asi como:

UPDATE Productos 
SET Proveedor1Codigo = @proveedor1Codigo, 
    Proveedor2Codigo = @proveedor2Codigo
WHERE Productos.Codigo = @empresaCodigo

 

Opción 2

Esta es la mas performante de las 3 opciones. El único problema es que solo es posible en SQL Server 2008.

Está implementada utilizando una Tabla como Parámetro y realizando toda la actualización mediante una sentencia SQL.

Veamos como hacelo:

Se crea un tipo de dato Table en SQLServer

CREATE TYPE UnionProductosTbl AS TABLE 
(
    EmpresaCodigo int,
    Proveedor1Codigo varchar(7),
    Proveedor2Codigo int
)

 

Se crea el Procedimiento Almacenado usando ese tipo como parámetro:

CREATE PROCEDURE ActualizarCodigosProveedores
    @unionProductosTbl dbo.UnionProductosTbl READONLY
AS
BEGIN
 
    UPDATE Productos p
    SET p.Proveedor1Codigo = tbl.Proveedor1Codigo,
    p.Proveedor2Codigo = tbl.Proveedor2Codigo
    FROM Productos
    INNER JOIN @unionProductosTbl tbl ON p.Codigo = tbl.empresaCodigo
    
END

 

Y el proceso en el código:

//Lectura del Archivo
               FileHelperEngine engine = new FileHelperEngine(typeof(UnionProductos));
               //Devuelve como DataTable
               DataTable unionLeidoDT = engine.ReadFileAsDT(nombreArchivo);
 
               //El proceso de actualización
               string stringDeConexion = "XXXXXXXXXXXXXXXX";
               using (SqlConnection conn = new SqlConnection(stringDeConexion))
               {
                   conn.Open();
                   SqlCommand cmd = new SqlCommand("nombreStore", conn);
                   //Se define un parámetro de tipo Structured para que reciba un DataTable
                   SqlParameter par = cmd.Parameters.Add("@unionProductosTbl", 
                       SqlDbType.Structured);
                   par.Value = unionLeidoDT;
                   cmd.ExecuteNonQuery();
               }
               
 

Realizando el proceso con 17.000 registros los resultados fueron los siguientes (los tiempos son orientativos):

Opción Tiempo

Utilizando EF

8 minutos

Utilizando ADO.NET nativo procesando registro a registro con un Store Procedure

4 minutos

Utilizando un Store Procedure en SQL 2008 con una tabla como parámetro

4 segundos !!

 

Para finalizar, la opción de realizar el proceso batch usando una tabla como parámetro de un Store es la mejor opción si la prioridad es la performance de la solución.

Tags: ,

ADO.NET | Entity Framework | SQL Server

Acerca de los Autores

Este es el blog del equipo de VEMN SA 
Presentaremos temas que nos parezcan de interés sobre tecnología .NET, Procesos y Metodologías y todo aquello relacionado con el proceso de desarrollo de Software

Month List

BlogRoll

Download OPML file OPML