[Tutorial] JQUERY + ODATA + Excel Power Pivot
Introducción
Hola que tal, siguiendo los artículos inspirados en el trabajo del Mega Maestro Stephen Walther, vamos a revisar la inserción y muestra de datos mediante oData. oData fue desarrollado por Microsoft para ser un estándar abierto para la comunicación de datos a través de Internet. Este estándar es compatible con JSON y REST, protocolos fácilmente abordables con AJAX.OData es lo que antes conocimos como Astoria, y luego ADO.NET Data Services, y es utilizado por Sharepoint Server 2010, Azure, Excel 2010, Sql Server 2008 entre otros.Para aprender más sobre OData, pueden visitar :
http://www.odata.org
http://msdn.Microsoft.com/en-US/Data/bb931106.aspx
Lo mejor de todo, es que cuando utilizamos .NET Framework podemos exponer fácilmente los datos de una BD mediante OData mediante un servicio WCF. La idea es hacer crear una página que sea un CRUD.Para eso, al igual que en el Post Anterior, vamos a crear una Base de Datos (distinta al post anterior, para poder ver las ventajas de ocupar Power Pivot de Excel 2010)
Creando la BD
Vamos a crear dos tablas con una estructura bastante sencilla.
Tabla Películas

Tabla Género

Y Finalmente la relación entre ellas:
Creando el Modelo
Vamos a ocupar Entity Framework para la creación de nuestro modelo, los pasos los expliqué en mi post anterior, pero si no quieres ir a verlos, los pego acá:
Vamos a seleccionar ASP.NET Empty Web Aplication, que como saben, es una aplicación web limpia, sin los templates que nos ofrece Visual Studio 2010.Según nuestro diseño (Figura 1) , tenemos que crear el Modelo de Entidades, para ello vamos a utilizar ADO.NET Entity Framewok. Para esto:
- Seleccionamos la opción Agregar nuevo Item del proyecto, seleccionamos ADO.NET Entity Data Model.
-
Luego le damos un nombre, en mi caso MiAgendaBD, luego seleccionamos “Generar desde una Base de Datos” y seleccionamos nuestra conexión.

-
Luego podemos elegir las tablas que van a formar parte del modelo, que en nuestro caso es solo una, finalmente vamos a ver nuestro Modelo Generado:
Agregar el Servicio WCF
Vamos a nuestro proyecto, agregar->WCF Data Service

Una vez agregado el servicio, vamos a agregar el código necesario para que podamos realizar todas operaciones que necesitamos ( para el ejemplo, solo leer e insertar, pero ya sabes, puedes seguir completando el ejemplo), veamos el código:
Imports System.Data.Services
Imports System.Data.Services.Common
Imports System.Linq
Imports System.ServiceModel.Web
Public Class VideoClubDS
Inherits DataService(Of VideoClubEntities)
Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)
config.SetEntitySetAccessRule("*", EntitySetRights.All)
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2
End Sub
End Class
Con estos estamos seteando las reglas de acceso a todas las entidades (por eso el “*”) con todos los permisos (obviamente esto para simplificar el ejemplo, pero puedes dar valores individuales sobre las entidades según las operaciones sobre ellas).
El formulario HTML
Este formulario, como vez, no es ninguna maravilla en diseño, lo que debe hacer es poder ingresar películas a la base de datos y posteriormente desplegar en pantalla el listado de ellas.
Como podrás ver, existe un select Genero (estamos hablando de solo elementos HTML en esto, nada de WebControls y sus lindos Viewstates), el cual debemos enlazar con la tabla Genero que se expone a través de OData.
Obtener los datos de Genero para el Select
Antes que nada vamos a hacer la referencia a los archivos necesarios para utilizar jQuery
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js" type="text/javascript"></script>
<script src="Scripts/json2.js" type="text/javascript"></script>
Como ves estamos utilizando Microsoft AJAX CDN (puedes ver mi articulo sobre el tema aquí),
Voy a crear una función Javascript que me permita obtener los datos tanto de Genero y de Películas, esta función la modifiqué de los ejemplos de la documentación de OData que la puedes ver aquí.
<script type="text/javascript">
var ajaxRequest;
var aValores = new Array();
$(document).ready(function () {
GetData('Genero');
}); function GetData(set) {
var materializer;
switch (set) {
case 'Genero':
materializer = ObtieneRegistroGenero;
break;
case 'Peliculas':
materializer = ObtieneRegistroPeliculas;
break;
default:
alert('Error!');
} if (ajaxRequest != null)
ajaxRequest.abort();
ajaxRequest = $.getJSON(
"VideoClubDS.svc/" + set,
function (data) {
var array = [];
$.each(data.d, function (i, item) {
materializer(array, item)
if (set == 'Genero') { aValores[item.Id] = item.Nombre; }
});
}
);
}
function ObtieneRegistroGenero(array, item) {
$('#dd_genero').append('<option value="' + item.Id + '">' + item.Nombre + '</option>');
}
function ObtieneRegistroPeliculas(array, item) {
$('#listadoPeliculas > tbody:last').append('<tr><td>' + item.Id + '</td><td>' + item.Nombre + '</td><td>' + item.Duraccion + '</td><td>' + item.Año + '</td><td>' + aValores[item.GeneroId] + '</td></tr>');
}
Vamos por parte, lo primero que hacemos es declarar la variable ajaxRequest que va a tener el resultado de la ejecución de la llamada asíncrona y aValores que es un arreglo que nos va a servir para armar la tabla con las películas (ya lo explico más adelante)Luego con $(document).ready(function… nos aseguramos que ya terminó de cargar la página para llenar el select.
Paso siguiente es llamar a la función GetData con el parámetro set, que indica de que tabla queremos hacer el select. Como vez, esta función utiliza una variable materializer que obtiene la referencia la función, mediante este patrón de diseño es posible utilizar las funciones ObtieneRegistroGenero y ObtieneRegistroPeliculas de igual forma para armar los correspondientes objetos DOM.
En la sección:
ajaxRequest = $.getJSON(
"VideoClubDS.svc/" + set,
Corresponde a la llamada del servicio, el parámetro set contiene el nombre de la tabla a consultar. La línea con el código:
if (set == 'Genero') { aValores[item.Id] = item.Nombre; }
Nos sirve para almacenar los valores de género, de tal manera que cuando obtengamos los valores de la tabla, convirtamos los GeneroID a la descripción correspondiente, lo puedes ver en el código de la función ObtieneRegistroPeliculas :aValores[item.GeneroId], de otra manera, tendríamos que hacer otra llamada al WS. (Estoy averiguando más como hacerlo sin que esto suceda).
Y para terminar, las funciones ObtieneRegistroXXXX arman los DOM, agregando objetos <option> para genero, y <tr> para las películas.
Insertando las Películas
Atachamos al botón grabar la función que contiene el comportamiento de insertar. Notar que me equivoqué en la palabra Duración, escribí Duraccion :P. Bueno, acá hacemos la llamada al Servicio VideoClubDS.svc/Peliculas y antes tenemos que serializar el objeto a JSON, para eso utilizamos la librería JSon2:
La librería que usaremos la puedes descargar desde:
http://www.json.org/js.html
$("#btnGrabar").click(function () {
var oPelicula = { Nombre: $("#tx_nombre").val(), Duraccion: $("#tx_duracion").val(), Año: $("#tx_año").val(), GeneroId: $("#dd_genero").val() };
var oPelicula = JSON.stringify(oPelicula);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "VideoClubDS.svc/Peliculas",
data: oPelicula,
dataType: "json",
success: insertCallback
});
});
function insertCallback(result) {
var nuevaPelicula = result["d"];
alert("La Pelicula se ha grabado con el ID " +
nuevaPelicula.Id);
getPeliculas()
}
function borraTabla() {
n = 0;
$('#listadoPeliculas tr').each(function () {
if (n > 0) $(this).remove(); n++;
});
}
function getPeliculas() {
borraTabla();
GetData('Peliculas');
}
Una vez que se ejecuta la función llamamos se ejecuta insertCallback, en donde mostramos el Id de la película recién insertada y llamamos la función getPeliculas, que se encarga borrar la tabla (para que no se repitan las filas al hacer append), desde la fila 1, o si no borraríamos los títulos, y eso no se vería muy bien.
Video Funcionando…
Power Pivot
Según las definiciones:
Microsoft PowerPivot es un complemento de análisis de datos de Excel 2010, antes conocido como “Project Gemini”, que proporciona una potencia computacional sin precedentes directamente dentro de Excel 2010.
PowerPivot proporciona su enlace a los usuarios de negocios de BI, mientras permite a las organizaciones monitorear y manejar la colaboración eficientemente usando SharePoint 2010 y SQL Server 2008 basado en herramientas de gestión.
Puedes ver más info en el blog del equipo de Power Pivot
http://blogs.msdn.com/powerpivot/default.aspx y este este excelente post sobre el tema de Juan Alvarado : Uso de oData con Powerpivots como consumidor
En mi caso voy a consumir de manera rápida (sin mucho sentido de la estadística) el servicio, más que nada para que veas las potencialidades del producto.
Elegimos obtener los datos desde un Data Feed
Luego nos aparece la pantalla del asistente, en donde escribimos la dirección de nuestro servicio y probamos (solo para estar re seguros)
Luego seleccionamos las tablas expuestas por el servicio que van a participar en el análisis:
y luego se extraen los datos a planillas Excel que puedes utilizar con Power Pivot:

Descarga el ejemplo desde acá
Espero que te sirva!
Saludos,
Gonzalo