Académique Documents
Professionnel Documents
Culture Documents
Introducción
Se creará una arquitectura de software compuesta de una DAL (Capa de Acceso a Datos)
usando DataSets y una capa de presentación compuesta por páginas ASP.NET que
compartan un diseño similar.
El siguiente paso es crear una referencia a la base de datos en el Server Explorer de Visual
Studio. Con esto podremos agregar tablas, procedimientos almacenados, vistas, etc. además
de poder analizar datos de las tablas o crear consultas personalizadas directamente o
mediante el Generador de Consultas (Query Builder). Además, cuando construimos Data
Uso de la Base de Datos en la carpeta App_Data
A database placed in the App_Data folder is automatically added to the Server Explorer.
Assuming you have SQL Server 2005 Express Edition installed on your machine you
should see a node named NORTHWND.MDF in the Server Explorer, which you can
expand and explore its tables, views, stored procedure, and so on (see Figure 2).
The App_Data folder can also hold Microsoft Access .mdb files, which, like their SQL
Server counterparts, are automatically added to the Server Explorer. If you don't want to
use any of the SQL Server options, you can always download a Microsoft Access version
of the Northwind database file and drop into the App_Data directory. Keep in mind,
however, that Access databases aren't as feature-rich as SQL Server, and aren't designed to
be used in web site scenarios. Furthermore, a couple of the 35+ tutorials will utilize certain
database-level features that aren't supported by Access.
Esta capa separada se conoce como DAL, que se implementa típicamente como un
proyecto de Biblioteca de Clases. En principio, esta arquitectura de capas nos permite
manejar de forma aislada los elementos relacionados con una u otra sin afectar ambas
Todo el código específico al origen de datos, relacionado con los comandos SELECT,
INSERT, UPDATE, y DELETE debe ubicarse en la DAL. La capa de presentación sólo
debe hacer llamadas a la DAL para cualquier petición de datos.
La BD Nortwind, por ejemplo, contiene las tablas Products y Categories que guardan los
productos en venta y sus categorías relacionadas. En la DAL tendremos métodos como:
Por ejemplo, el DataReader y el DataSet no son por default objetos de este tipo ya que su
esquema se define por las columnas que regresa la consulta que envía los datos
La figrua 3 ilustra el flujo de trabajo entre las diferentes capas de una aplicación con Data
Set
La clase TableAdapter funcionará como la Capa de Acceso a Datos. Para este caso,
contendrá los métodos GetProducts(), GetProductByCategoryID(categoryID), y demás
que se invocarán desde la capa de presentación.El asistente pide seleccionar la BD a
trabajar.
Dar siguiente para ir a la pantalla final. Aquí se pide seleccionar los métodos para el
TableAdapter
Figura 11: Cambio del nombre del método
Los objetos agregados nos sirven para tener acceso a los datos con código tal como:
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
Northwind.ProductsDataTable products;
products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow productRow in products)
Response.Write("Product: " + productRow.ProductName + "<br />");
Construir la siguiente página web que enlaza el DataTable generado por el método
GetProducts() a un GridView dentro del evento Page_Load
AllProducts.aspx
</asp:GridView>
</p>
</div>
</form>
</body>
</html>
AllProducts.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class AllProducts : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ProductsTableAdapter productsAdapter = new
ProductsTableAdapter();
GridView1.DataSource = productsAdapter.GetProducts();
GridView1.DataBind();
}
}
In the final step we can choose which data access patterns to use, as well as customize the
names of the methods generated. For the Fill pattern, let's change the name to
Figura 17: Seleccionar los Nombres de loa métodos
Ahora crearemos una página que muestre sólo los productos de una categoría específica.
Beverages.asp
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>Beverages</h2>
<p>
<asp:GridView ID="GridView1" runat="server"
/>
</asp:GridView>
</p>
</div>
</form>
</body>
</html>
Beverages.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class Beverages : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ProductsTableAdapter productsAdapter = new
ProductsTableAdapter();
GridView1.DataSource =
productsAdapter.GetProductsByCategoryID(1);
GridView1.DataBind();
}
}
Figure 21: Cada consulta de Insert, Update, y Delete se envían de forma inmediata a la BD
en el enfoque de consulta individual
Figura 22: Todos los cambios se sincronizan con la BD cuando se usa el enfoque Update
Method
Figura 23: Verificar que el TableAdapter contiene elementos en las propiedades
InsertCommand, UpdateCommand, and DeleteCommand
.
Figura 24: Configurar las sentencias INSERT, UPDATE, y DELETE en el Generador de
Consultas
Probar el siguiente código de ejemplo con el enfoque de lotes para duplicar el precio de los
productos no descontinuados con 25 unidades en bodega o menos:
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
Northwind.ProductsDataTable products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow product in products)
if (!product.Discontinued && product.UnitsInStock <= 25)
product.UnitPrice *= 2;
productsAdapter.Update(products);
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
18.0m, 39, 15, 10, false, 1);
productsAdapter.Insert("New Product", 1, 1,
"12 tins per carton", 14.95m, 15, 0, 10, false);
Métodos Personalizados
Click derecho en el Diseñador del DataSet. Click en Agregar Consulta. En la segunda
pantalla del asistente:
Figura 25: Creación de un método para agregar una nueva fila a la tabla Products.
Los métodos insert por default regresan el número de filas afectadas. Queremos que el
método InsertProduct regrese el valor de la consulta, no el número de filas. Para esto,
seleccionar el valor Scalar:
Figure 29: Cambio de ExecuteMode a Scalar
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
int new_productID = Convert.ToInt32(productsAdapter.InsertProduct
("New Product", 1, 1, "12 tins per carton", 14.95m, 10, 0, 10,
false));
5: Completar la DAL
Podemos aumentar el método inicial de GetProducts(), para incluir los valores de las
columnas CategoryName y CompanyName, que actualizarán el DataTable.
Usando JOIN el Diseñador del DataSet no podría autogenerar los métodos para trabajr con
los datos usando el enfoque directo.
PARA ENTREGAR
TABLE ADAPTERS
1.- Crear los siguientes TableAdapters y métodos usando las consultas siguientes
Notar que las consultas en el ProductsTableAdapter incluyen las subconsultas para tomar
los nombres de cada categoría y proveedor
ProductsTableAdapter
o GetProducts:
SELECT ProductID, ProductName, SupplierID,
CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock,
UnitsOnOrder, ReorderLevel, Discontinued ,
(SELECT CategoryName FROM Categories WHERE
Categories.CategoryID = Products.CategoryID) as
CategoryName, (SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID)
as SupplierName
FROM Products
o GetProductsByCategoryID:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued , (SELECT CategoryName
FROM Categories WHERE Categories.CategoryID =
Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers WHERE
Suppliers.SupplierID = Products.SupplierID)
as SupplierName
FROM Products
WHERE CategoryID = @CategoryID
o GetProductsBySupplierID:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued , (SELECT CategoryName
FROM Categories WHERE Categories.CategoryID =
Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers WHERE
Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM Products
WHERE SupplierID = @SupplierID
o GetProductByProductID:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued , (SELECT CategoryName
FROM Categories WHERE Categories.CategoryID =
Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers WHERE
Suppliers.SupplierID = Products.SupplierID)
as SupplierName
FROM Products
WHERE ProductID = @ProductID
• CategoriesTableAdapter
o GetCategories:
SELECT CategoryID, CategoryName, Description
FROM Categories
o GetCategoryByCategoryID:
SELECT CategoryID, CategoryName, Description
FROM Categories
WHERE CategoryID = @CategoryID
• SuppliersTableAdapter
o GetSuppliers:
SELECT SupplierID, CompanyName, Address,
City, Country, Phone
FROM Suppliers
o GetSuppliersByCountry:
SELECT SupplierID, CompanyName, Address,
City, Country, Phone
FROM Suppliers
WHERE Country = @Country
o GetSupplierBySupplierID:
SELECT SupplierID, CompanyName, Address,
City, Country, Phone
FROM Suppliers
WHERE SupplierID = @SupplierID
• EmployeesTableAdapter
o GetEmployees:
SELECT EmployeeID, LastName, FirstName, Title,
HireDate, ReportsTo, Country
FROM Employees
o GetEmployeesByManager:
SELECT EmployeeID, LastName, FirstName, Title,
HireDate, ReportsTo, Country
FROM Employees
WHERE ReportsTo = @ManagerID
o GetEmployeeByEmployeeID:
SELECT EmployeeID, LastName, FirstName, Title,
HireDate, ReportsTo, Country
FROM Employees
WHERE EmployeeID = @EmployeeID