متدهای Insert(), Update(), Delete() ایجاد شده توسط روش تاثیر مستقیم روی پایگاه داده، به ویژه برای جدولهایی با ستونهای زیاد، میتواند دست و پا گیر باشد.
برای ایجاد متدهای سفارشی به محیط طراحی DataSet بروید. روی TableAdapter راست کلیک کرده و Add Query را انتخاب کنید، در پنجره دوم میتوانیم مشخص کنیم که چه نوع کوئری میخواهیم ایجاد کنیم. اجازه دهید یک متد که یک محصول جدید اضافه کرده و ProductID آن را برگرداند، ایجاد کنیم. بنابراین گزینه INSRT را انتخاب میکنیم.
در مرحله بعدی CommandText مربوط به InsertCommand دیده میشود. به پایان این کوئری عبارت SELECT SCOPE_IDENTITY() را اضافه کنید، این عبارت مقدار ستون IDENTITY آخرین رکورد درج شده را برمیگرداند. مطمئن شوید که در پایان دستور INSERT و قبل از اضافه کردن عبارت، از نقطه ویرگول (;) استفاده کردهاید.
در پایان متد جدید را InsertProduct بنامید.
وقتی به محیط طراحی DataSet برمیگردید، میبینید که یک متد به نام InsertProduct به ProductsTableAdapter اضافه شده است. اگر متد جدید دارای پارامتر نباشد، ممکن است نقطه ویرگول پایان دستور INSERT را فراموش کرده باشید. متد InsertProduct را پیکربندی (Configure) کرده و نقطه ویرگول را اضافه نمایید. به طور پیش فرض، متدهای Insert به صورت None Query ایجاد میشوند، بدین معنی که تعداد سطرهایی که درج شدهاند را برمیگردانند. ولی ما میخواهیم این متد مقداری که کوئری برمیگرداند را برگرداند نه تعداد سطرها را. برای این منظور مشخصه ExecuteMode متد InsertProduct را به Scalar تغییر دهید.
دو روش عمومی برای درج کردن، بروزرسانی و حذف داده وجود دارد. روش اول، شامل ایجاد متدهایی است که وقتی فراخوانی میشوند یک دستور Insert, Update و یا Delete ایجاد میکنند که بر روی یک رکورد از پایگاه داده اثر میگذارد.
روش دیگر؛ بروزرسانی یک DataSet, DataTable و یا مجموعهای از DataRows است که در یکبار فراخوانی متد انجام میشود. در این روش، توسعه دهنده DataRows را در یک DataTable درج میکند، بروزمیرساند و یا تغییر میدهد و سپس آنها را به یک متد بروزرسانی ارسال میکند. سپس این متد DataRows که در دریافت کرده را بررسی و تعیین میکند که کدام یک اضافه شده است، تغییر کرده است و یا حذف شده است و پس از آن برای هر رکورد یک دستور مناسب پایگاه داده صادر میکند.
TableAdapter به طور پیش فرض از روش بروزرسانی بستهای (روش دوم) استفاده میکند، اما از روش تاثیر مستقیم روی پایگاه داده (روش اول) نیز پشتیبانی میکند. زمانی که گزینه "Generate Insert, Update, and Delete statements" را از Advanced Properties هنگام ایجاد TableAdapter انتخاب میکنیم، ProductsTableAdapter دارای یک متد Update() میشود که روش بروزرسانی بستهای را ایجاد میکند. هر دو روش تغییر داده از مشخصههای InsertCommand, UpdateCommand, DeleteCommand مربوط به TableAdapter برای صدور دستورات insert, update, delete به پایگاه داده استفاده میکنند. شما میتوانید مشخصههای InsertCommand, UpdateCommand, DeleteCommand را با کلیک کردن روی TableAdapter در محیط طراحی DataSet و مراجعه به پنجره Properties آن، بررسی کنید و تغییر دهید.
برای امتحان کردن و یا تغییر دادن هر کدام از مشخصههای دستورات پایگاه داده، روی زیرمشخصه CommandText کلیک کرده و Query Builder را اجرا کنید.
کدهای نمونه زیر نشان میدهد که چگونه روش بروزرسانی بستهای را برای دو برابر کردن قیمت محصولاتی که تولید آنها متوقف نشده و 25 عدد و یا کمتر از آن موجود است:
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
// For each product, double its price if it is not discontinued and
// there are 25 items in stock or less
Northwind.ProductsDataTable products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow product in products)
if (!product.Discontinued && product.UnitsInStock <= 25)
product.UnitPrice *= 2;
// Update the products
productsAdapter.Update(products);
کدهای زیر نشان میدهند که چگونه از روش مستقیم روی پایگاه داده برای حذف یک محصول خاص، سپس بروزرسانی دیگری و اضافه کردن یک محصول جدید استفاده کنیم:
NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
new NorthwindTableAdapters.ProductsTableAdapter();
// Delete the product with ProductID 3
productsAdapter.Delete(3);
// Update Chai (ProductID of 1), setting the UnitsOnOrder to 15
productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
18.0m, 39, 15, 10, false, 1);
// Add a new product
productsAdapter.Insert("New Product", 1, 1,
"12 tins per carton", 14.95m, 15, 0, 10, false);
در این زمان کلاس ProductsTableAdapter دارای یک متد است، GetProducts()، که تمام محصولات موجود در پایگاه داده را برمیگرداند. تا زمانی که بخواهیم با تمام محصولات کار کنیم این متد مناسب است، اما گاهی مواقع نیاز است که اطلاعات مربوط به یک محصول خاص را بازیابی کنیم، و یا تمام محصولاتی که در یک گروه قرار دارند را میخواهیم. برای اضافه کردن چنین توابعی به لایه دسترسی داده، میتوانیم متدهای دارای پارامتر به TableAdapter اضافه کنیم.
بدین منظور متد GetProductsByCategoryID(categoryID) را اضافه میکنیم. برای اضافه کردن متد جدید به DAL به محیط طراحی DataSet رفته و با کلیک راست در ProductsTableAdapter گزینه Add Query را انتخاب میکنیم.
در قدم اول باید مشخص کنیم که یک دستور SQL ایجاد میکنیم و یا از یک رویه ذخیره شده استفاده میکنیم. با انتخاب ایجاد یک دستور SQL؛ ad-hoc SQL statement؛ به مرحله بعد میرویم. در این مرحله پرسش میشود که چه نوع پرس و جوی SQL میخواهیم استفاده کنیم. از آنجایی که میخواهیم کلیه محصولاتی که در یک گروه قرار دارند را برگردانیم، از گزینه select که چندین سطر برمیگرداند، استفاده میکنیم.
قدم بعدی تعیین SQL Query برای دسترسی به دادهها است. از آنجایی که ما میخواهیم تمام محصولات مربوط به یک گروه خاص را برگردانیم، از دستوری مشابه GetProducts() استفاده میکنیم، اما شرط زیر را به آن اضافه میکنیم: where categoryID=@categpryID.
در مرحله آخر میتوانیم الگوی مورد استفاده برای دسترسی به داده را مشخص کنیم، مانند تعیین نام متدی که ایجاد شده است. نام الگوی Fill را به FillByCategoryID و الگوی برگرداندن DataTable را به GetProductsByCategoryID تغییر میدهیم.
بعد از پایان مراحل، محیط طراحی DataSet شامل یک متد جدید برای TableAdapter است.
متدهای دارای پارامتر را میتوان در محیط طراحی DataSet تست کرد. در TableAdapter بر روی متد راست کلیک کرده و Preview Data را انتخاب کنید. سپس مقدار پارامتر را وارد کرده و کلید Preview را کلیک کنید.
به وسیله GetProductsByCategoryID (categoryID) در DAL میتوانیم در یک صفحه ASP.NET محصولاتی که در یک گروه هستند را نمایش دهیم. نمونه کد زیر تمام محصولات گروه Beverages که دارای categoryID برابر 1 هستند را نشان میدهد:
Beverages.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Beverages.aspx.cs"
Inherits="Beverages" %>
<!DOCTYPE html PUBLIC "//
W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.
dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Beverages</h1>
<p>
<asp:GridView ID="GridView1" runat="server"
CssClass="DataWebControlStyle">
<HeaderStyle CssClass="HeaderStyle" />
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
</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();
}
}