quan he database voi c#
TRANSCRIPT
QUAN HỆ C# VÀ DATABASE :: KẾT NỐI C# VỚI DATABASE
Việc hiểu quan hệ giữa C# và Database trong việc xây dựng các ứng dụng (website) là rất quan trọng, Trong loạt bài viết này sẽ cung cấp các kiến thức nền tảng trong việc kết nối C# với Database. Bạn xem và bổ xung kiến thức cho khả năng lập trình của mình.
Trong bài viết đầu tiên này mình sẽ giới thiệu về Kết nối C# với Database
Microsoft cung cấp các "data provider" như sau: Data Provider Namespace Connection Class
ODBC System.Data.Odbc OdbcConnectionOLE DB System.Data.Oledb OledbConnectionOracle System.Data.OracleClient OracleConnectionSQL Server System.Data.SqlClient SqlConnectionSQL Server CESystem.Data.SqlServerCe SqlCeConnection
Trong đó thường sử dụng nhất là: ODBC, OLE DB, SQL Server. Trong đó SQL là được dùng rộng rãi nhất,
vì vậy SQL sẽ được chọn để minh họa. Và mình sẽ sử dụng Northwind database là cơ sở dữ liệu mẫu có
sẵn khi bạn cài SQL server.
Ta sẽ bắt đầu bằng việc mở kết nối như ví dụ dưới đây:
01 using System;
02 using System.Data;03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 public partial class Database : System.Web.UI.Page
14 {
15 protected void Page_Load(object sender, EventArgs e)
16 {
17 string connectString = @"Server =.\SQL2005;Initial
Catalog=Northwind;User ID=sa;Password=******";
18 // Tạo một connection tới máy chủ
19 SqlConnection conn = new SqlConnection(connectionString);
20 try
21 {
22 conn.Open();23 //thuc hien cac cong viec can thiet o day
24 }
25 catch (SqlException ex)
26 {
27 Console.WriteLine("Error: " + ex);
28 }
29 finally
30 {
31 conn.Close();
32 }
33 }
34 }
Như vậy là xong việc kết nối.
Lưu ý:
Khối lệnh try..catch..finally là khối lệnh bạn nên luôn luôn thực hiện vì những lý do sau: Nếu bạn thực hiện lệnhconn.Open() thành công nó sẽ
nhảy xuống thực hiện khối lệnh trong finally là conn.Close(), còn nếu kết
nối không thành công nó sẽ xử lý ngoại lệ (Khối catch), sau đó cũng nhảy xuống thực hiện conn.Close(). Như vậy ta thấy dù kết nối thành công hay
ko thành công thì việc conn.Close() trong khối lệnh finally đều được thực
thi và nó sẽ hạn chế sự hao tổn tài nguyên. Vậy là cứ mở kết nối thực thi các
yêu cầu xong ta lại đóng kết nối lại -> Sẽ không tốn tài nguyên.
Nếu bạn sử dụng Windows Authentication thì chuỗi kết nối như sau: string connectString = @"Server =.\
SQL2005;database=Northwind;Integrated Security = true";
Tới đây ta đã xong bước đầu khi nhập môn C# with database.
QUAN HỆ C# VÀ DATABASE :: SQLCOMMAND
Có thể hiểu ngắn gọn là Lớp SqlCommand tạo một đối tượng để nắm giữ thông tin về mệnh lệnh. Nó
phải đi kèm với một kết nối tồn tại để tạo và thi hành mệnh lệnh được viết ra. Xem ví dụ sau:
01 using System;
02 using System.Data;03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 public partial class Database : System.Web.UI.Page
14 {
15 protected void Page_Load(object sender, EventArgs e)
16 {
17 // Khai báo chuỗi kết nối
18 string connectString = @"Server =.\SQL2005;Initial Catalog=BaiTap;User ID=sa;Password=******";
19 // Khai báo câu truy vấn
20 string sql = @"SELECT count(*) FROM Customers";
21 // Tạo một connection tới máy chủ
22 SqlConnection conn = new SqlConnection(connectString);23 try
24 {
25 conn.Open();
26 SqlCommand cmd = new SqlCommand(sql, conn);27 Label1.Text="Số bản ghi:= "+cmd.ExecuteScalar();
28
29 }
30 catch (SqlException ex)
31 {
32 Console.WriteLine("Error: " + ex);
33 }
34 finally
35 {
36 conn.Close();37 }
38 }
39 }
Trong trang aspx bạn tạo một Label (<asp:Label ID="Label1" runat="server"
/>) để hiển thị kết quả. Khi chạy sẽ cho kết quả là: Số bản ghi:= 91 ( 91 là
tổng số bản ghi trong bảng Customers)
Lưu ý:
- Một SqlCommand thông thường được khởi tạo như trên nó phải đi với một
query và một connection, cụ thể ở đây là sql và conn. Nó nên đặt trong khối
lệnh try vì nếu đặt ở ngoài khi kết nối không thành công thì chương trình
ngưng hoạt động, ở tình trạng treo mà vẫn tiêu hao tài nguyên.
- Các cách thực thi của SqlCommandPhương thức (Method) Giá trị trả về (Return Value)
ExecuteNonQuery()Trả về số hàng bị ảnh hưởng bởi câu lệnh SQL. Thường được sử dụng với các câu lệnh không trả về dữ liệu như Insert, delete, update,...
ExecuteScalar()
Trả về hàng đầu tiên, cột đầu tiên của (một tập hợp) kết quả, các hàng/cột còn lại (nếu có) sẽ bị bỏ qua. Thường được sử dụng với các câu lệnh chỉ trả về 1 hàng, 1 cột kết quả (vd đếm số lượng nhân viên trong công ty).
ExecuteReader()Trả về đối tượng SqlDataReader - thường dùng cho việc đọc kết quả trả về của câu lệnh SQL là 1 tập hợp gồm nhiều hàng, nhiều cột - đối tượng này sẽ được giới thiệu kỹ hơn trong phần sau.
ExecuteXmlReader()Trả về đối tượng XmlReader - thường dùng để đọc kết quả trả về của câu lệnh SQL được lưu trữ ở dạng XML.
Trong ví dụ trên câu lệnh truy vấn chỉ trả về một giá trị nên ta sử
dụng ExecuteScalar() Trường hợp câu truy vấn trả về nhiều giá trị (Dữ liệu
dạng bảng) khi đó ta sẽ sử dụng ExecuteReader() xem ví dụ sau:
01 using System;
02 using System.Data;03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 public partial class Database : System.Web.UI.Page
14 {
15 protected void Page_Load(object sender, EventArgs e)
16 {
17 string strHTML = "";
18 strHTML+="<table border=\"0\" width=\"550\" cellspacing=\"1\" cellpadding=\"0\" bgcolor=\"#999966\" id=\"table2\">";
19 strHTML+=" <tr>";
20 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">CustomerID</font></td>";
21 strHTML += " <td bgcolor=\"#CC3300\"
align=\"center\"><font color=\"#FFFFFF\">CompanyName</font></td>";
22 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">ContactName</font></td>";
23 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">Country</font></td>";
24 strHTML+=" </tr>";
25 // Khai báo chuỗi kết nối
26 string connectString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
27 // Khai báo câu truy vấn
28 string sql = @"SELECT TOP 10 CustomerID, CompanyName, ContactName, Country FROM Customers ";
29 // Tạo một connection tới máy chủ
30 SqlConnection conn = new SqlConnection(connectString);31 try
32 {
33 conn.Open();
34 SqlCommand cmd = new SqlCommand(sql, conn);35 SqlDataReader reader = cmd.ExecuteReader();
36 while (reader.Read())
37 {
38 strHTML += " <tr>";
39 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader.GetValue(0) + "</td>";
40 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader.GetValue(1) + "</td>";
41 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader.GetValue(2) + "</td>";
42 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader.GetValue(3) + "</td>";
43 strHTML += " </tr>";
44 }
45 reader.Close();//Đóng SqlDataReader
46 }
47
48 catch (SqlException ex)
49 {
50 Console.WriteLine("Error: " + ex);
51 }
52 finally
53 {
54 conn.Close();
55 }
56 strHTML += "</table>";57 Literal1.Text = strHTML;
58 }
59 }
Trong trang aspx bạn cần tạo <asp:Literal ID="Literal1" runat="server" />
để hiển thị dữ liệu
Kết quả hiển thị như minh họa sau:
Bạn có thể download mã nguồn ví dụ trên tại đây
Như vậy khi chạy chương trình nó xuất ra nhiều kết quả khác nhau (được thể hiện dạng bảng). Ở đây ta
thấy xuất hiện thêm SqlDataReader cái này sẽ được giới thiệu ở bài sau. Tại đây bạn cứ tạm hiểu nó như
là công cụ ghi nhận thông tin từ cmd và xuất ra màn hình!
Còn một phương thức nữa rất hay sử dụng là phương thức ExecuteNonQuey() mục đích của nó là thực
thi các query không trả về giá trị (Các câu query dạng Insert, Update, Delete). Bạn xem ví dụ sau:
01 protected void Page_Load(object sender, EventArgs e)
02 {
03 string connectString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
04 string queryInsert = @"INSERT INTO Employees (firstname,lastname) VALUES ('Pete','Houston')";
05 string queryDelete = @"DELETE FROM Employees WHERE firstname = 'Pete' AND lastname = 'Houston'";
06 // Tạo một kết nối tới máy chủ
07 SqlConnection conn = new SqlConnection(connectString);
08 try
09 {
10 conn.Open();
11 // Thực thi câu lệnh Insert
12 SqlCommand cmdInsert = new SqlCommand(queryInsert, conn);
13 cmdInsert.ExecuteNonQuery();
14 // Thực thi lệnh Delete
15 SqlCommand cmdDelete = new SqlCommand(queryDelete, conn);
16 cmdDelete.ExecuteNonQuery();
17
18 }
19 catch (SqlException ex)
20 {
21 Console.WriteLine("Error: " + ex);
22 }
23 finally
24 {
25 conn.Close();
26 }
27 }
Khi thực thi code như ví dụ trên nó sẽ lần lượt thêm và xóa một bản ghi trong
bảng Employees bằng 2 lệnh
cmdInsert.ExecuteNonQuery();
cmdDelete.ExecuteNonQuery();
Tương tự như vậy bạn có thể viết câu lệnh cho việc update 1 bản ghi
Tiếp theo chúng ta sẽ tìm hiều về cách chuyền tham số
cho PARAMETERS (khá quan trọng): Không lẽ mỗi lần thay đổi lệnh ta lại
thay đổi các query? Từ bất cập mà parameters ra đời, nó cho phép ta truyền
vào các tham số một cách linh động và hiệu quả. Bạn xem ví dụ sau để hiểu
về PARAMETERS:
01string connectString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
02 string queryInsert = @"INSERT INTO Employees (firstname,lastname) VALUES (@firstname,@lastname)";
03 // Tạo một connection tới máy chủ
04 SqlConnection conn = new SqlConnection(connectString);05 try
06 {
07 conn.Open();
08 SqlCommand cmdInsert = new SqlCommand(queryInsert, conn);
09 //Khởi tạo
10 cmdInsert.Parameters.Add("@firstname", SqlDbType.NVarChar, 10);
11 cmdInsert.Parameters.Add("@lastname ", SqlDbType.NVarChar, 20);
12 //Truyền giá trị
13 cmdInsert.Parameters["@firstname"].Value = "Bui ";14 cmdInsert.Parameters["@lastname "].Value = "Hung";
15 //Thực thi lệnh
16 cmdInsert.ExecuteNonQuery();
17 }
18 catch (SqlException ex)
19 {
20 Console.WriteLine("Error: " + ex);
21 }
22 finally
23 {
24 conn.Close();25 }
Như vậy là trong bảng Employees bạn đã có thêm 1 Employee với fristname
= "Bui " và lastname ="Hung"
Nội dung về SqlCommand được giới thiệu sơ qua như vậy, Hy vọng qua bài
này bạn có thể hiểu hơn về SqlCommand
QUAN HỆ C# VÀ DATABASE :: SQLDATAREADER & DATASET
1.Data Readers
Khi bạn kết nối tới cơ sở dữ liệu và thi hành các query, dữ liệu thu nhận được cần phải có một ai đó xử
lý, chứ không lẽ kết nối đến SQL thêm, xóa, sửa.. xong rồi lại không biết được kết quả đúng hay sai, có
thực hiện được hay không, ít ra chúng ta phải xuất kết quả ra để theo dõi đúng không. Như vậy cần phải
có một đối tượng thu nhận các thông tin, đó chính là DataReaders
Trong bài trước mình có trình bày 1 ví dụ về có liên quan đến DataReaders nội dung ví dụ như sau:
01 using System;
02 using System.Data;03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 public partial class Database : System.Web.UI.Page
14 {
15 protected void Page_Load(object sender, EventArgs e)
16 {
17 string strHTML = "";
18 strHTML+="<table border=\"0\" width=\"550\" cellspacing=\"1\" cellpadding=\"0\" bgcolor=\"#999966\" id=\"table2\">";
19 strHTML+=" <tr>";
20 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">CustomerID</font></td>";
21 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">CompanyName</font></td>";
22 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">ContactName</font></td>";
23 strHTML += " <td bgcolor=\"#CC3300\" align=\"center\"><font color=\"#FFFFFF\">Country</font></td>";
24 strHTML+=" </tr>";
25 // Khai báo chuỗi kết nối
26 string connectString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
27 // Khai báo câu truy vấn
28 string sql = @"SELECT TOP 10 CustomerID, CompanyName, ContactName, Country FROM Customers ";
29 // Tạo một connection tới máy chủ
30 SqlConnection conn = new SqlConnection(connectString);31 try
32 {
33 conn.Open();
34 SqlCommand cmd = new SqlCommand(sql, conn);35 SqlDataReader reader = cmd.ExecuteReader();
36 while (reader.Read())
37 {
38 strHTML += " <tr>";
39 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader[0]+ "</td>";
40 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader[1] + "</td>";
41 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader[2] + "</td>";
42 strHTML += " <td bgcolor=\"#FFFFFF\">" + reader[3] + "</td>";
43 strHTML += " </tr>";
44 }
45 reader.Close();//Đóng SqlDataReader
46 }
47
48 catch (SqlException ex)
49 {
50 Console.WriteLine("Error: " + ex);
51 }
52 finally
53 {
54 conn.Close();
55 }
56 strHTML += "</table>";57 Literal1.Text = strHTML;
58 }
59 }
Kết quả thu được là các thông tin của trong câu lệnh SELECT TOP 10 CustomerID, CompanyName, ContactName, Country FROM
Customers
Với câu lệnh truy vấn trên nó sẽ trả về 10 bản ghi trong bảng Customers bạn có thể thấy muốn lấy dữ liệu là cột CustomerID bạn dùng reader[0]; 0
ở đây là vị trí Index theo thứ tự (Index được bắt đầu từ 0) trong thứ tự các cột
của câu truy vấn, Trong ví dụ của bài trước bạn thấy muốn lấy dữ liệu của cột CustomerID Mình dùngreader[0].GetValue(0) Ngoài cách dùng index
để hiển thị dữ liệu bạn cũng có thể dùng trực tiếp tên cột như sau:reader["CustomerID"]. Tới đây chắc các bạn cũng đã nắm được vị trí
index trong reader rồi nhỉ. Bạn sẽ thấy rằng hai cách hiển thị sẽ cho kết qua
như nhau nhưng theo mình bạn nên dùng trực tiếp tên cột vì đôi khi trong lập
trình bạn thay đổi thứ tự hiển thị trong câu truy vấn SQL.
Lưu ý:
- Thông thường data reader mà phải xử lý thông qua phương thức
‘ExecuteReader’ của một đối tượng command.
- Một DataReader có thể gọi là một stream đã kết nối tới cơ sở dữ liệu đọc dữ
liệu hiệu quả, theo một chiều và thu nhận dữ liệu theo từng dòng (row). Quy
tắc chung khi sử dụng data reader dơn giản là chỉ thu nhận và trình
bày kết quả thu được. Đây là điểm khác biệt lớn nhất giữa
dataReader và DataSet.
2.DataSet và DataAdapter
2.1.Dataset
Trong lúc làm việc ta không thể nào kết nối liên tục đến DataSource việc làm
này rất tốn tài nguyên của máy, chính vì lẽ đó mà .Net cung cấp cho bạn
DataSet mục đích là lưu trữ dữ liệu và chỉnh sửa cục bộ. Tức là toàn bộ thông
tin từ DataSource vẫn còn được lưu trữ trên DataSet khi ta đã ngắt kết nối.
Bạn hoàn toàn có thể thao tác trên DataSet như xem, chỉnh sửa sau đó
update dữ liệu lại cho DataSource. Nếu khi bạn không update thì việc thao
tác trên Dataset sẽ không ảnh hưởng gì đến DataSource cả!
DataSet được lưu trữ dưới dạng tập hợp các Tables và bạn cần xử lý thông
qua các lớp của Tables là DataRow, DataColumn.
Có nhiều cách xử lý DataSet nhưng nổi bậc hơn hẳn là 2 cách sử dụng:
- Sử dụng DataAdapter
- Sử dụng XML (cái này sẽ được trình bày trong bài viết sau)
2.2. DataAdapter:
DataAdapter được hiểu nôm na, như là cầu nối và truyền tải dữ liệu giữa
dataSet và dataSource. Mối quan hệ này được biểu diễn như sau: DataSource
~ DataAdapter ~ DataSet
Bạn xem ví dụ sau:
Trong trang aspx bạn cần tạo 1 gridview để hiển thị dữ liệu:
01
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DataSetDemo.aspx.cs"Inherits="DataSetDemo" %>
02<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
03<html xmlns="http://www.w3.org/1999/xhtml" >
04 <head runat="server">
05 <title>hmweb.com.vn</title>
06 </head>
07 <body>
08 <form id="form1" runat="server">
09 <div>
10 <asp:GridView ID="GridView1" runat="server" BackColor="White"BorderColor="#CCCCCC"
11 BorderStyle="None" BorderWidth="1px" CellPadding="3">
12 <RowStyle ForeColor="#000066" />
13 <FooterStyle BackColor="White" ForeColor="#000066" />
14 <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
15 <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
16 <HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
17 </asp:GridView>
18
19 </div>
20 </form>21 </body>22 </html>
Trong CodeFile (Code behind) bạn viết như sau:
01 using System;
02 using System.Data;03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12 public partial class DataSetDemo : System.Web.UI.Page
13 {
14 protected void Page_Load(object sender, EventArgs e)
15 {
16 DataTable dtb = new DataTable();
17 dtb = DemoDataSet();
18 GridView1.DataSource = dtb;19 GridView1.DataBind();
20 }
21 private DataTable DemoDataSet()
22 {
23 DataTable dtbTmp = new DataTable();
24 // Tạo connection string
25 string connString = @"Server =.\SQL2005;Initial
Catalog=Northwind;User ID=sa;Password=******";
26 // Tạo SQL query
27 string sql = @"SELECT TOP 8 CustomerID, CompanyName, ContactName, Country FROM Customers ";
28 // Tạo connection
29 SqlConnection conn = new SqlConnection(connString);
30 try
31 {
32 // Mở kết nối
33 conn.Open();
34 // Tạo một Adapter35 SqlDataAdapter da = new SqlDataAdapter(sql, conn);
36 // Tạo DataSet
37 DataSet ds = new DataSet();
38 // Đổ dữ liệu DataSet
39 da.Fill(ds, "Customers");
40 // Tạo DataTable từ dataSet41 dtbTmp = ds.Tables[0];
42 }
43 catch (Exception e)
44 {
45 // Bắt lỗi
46 Console.WriteLine(e.Message);
47 }
48 finally
49 {
50 // Đóng kết nối51 conn.Close();
52 }
53 return dtbTmp;
54 }
55 }
Trong ví dụ trên mình dùng chỉ số index (ds.Tables[0]) để bạn hiểu rằng
DataSet là một tập hợp nhiều DataTable. Khi bạn dùng da.Fill(ds,
"Customers") Như vậy ngoài cách sử dụng index bạn cũng có thể sử dụng
tên đã khai báo như sau: dtbTmp = ds.Tables["Customers"];
Chạy chương trình xong ta thấy, kết quả xuất ra như sau: (Bạn có thể
nhấn vào đây để down mã nguồn ví dụ trên để tham khảo)
Như vậy kết quả không khác mấy khi dùng SqlDataReader, nên nhớ rằng khi bạn thực hiện với mục đích
xuất thông tin ra thôi thì nên dùng SqlDataReader để thay thế cho DataSet, vì sẽ tiết kiệm được thời gian
và tài nguyên. Ví dụ trên nhằm mình họa một trong những tính năng của DataSet. Như vậy DataSet có
điểm gì nổi bậc hơn SqlDataReader, điểm nổi bậc ở đây chính là khả năng tùy biến cao, có thể chỉnh sửa
CSDL và lưu lại vào DataSource.
Bạn hãy xem ví dụ sau: 01 private void DataSetInsertAndView()
02 {
03 // Tạo connection strin
04 string connString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
05 // Tạo SQL query
06 string ins = @"INSERT INTO employees (firstname, lastname, titleofcourtesy, city, country) VALUES
07 (@firstname, @lastname, @titleofcourtesy, @city, @country) ";
08 // Tạo connection
09 SqlConnection conn = new SqlConnection(connString);
10 try
11 {
12 // Tạo Adapter13 SqlDataAdapter da = new SqlDataAdapter(qry, conn);
14 // Tạo và lấp đầy DataSet
15 DataSet ds = new DataSet();
16 da.Fill(ds, "employees");
17 // Lấy thông tin Table vào DataTable
18 DataTable dt = ds.Tables["employees"];
19 // Tạo thêm row mới
20 DataRow newRow = dt.NewRow();21 newRow["firstname"] = "Bui";22 newRow["lastname"] = "Hung";23 newRow["titleofcourtesy"] = "AND";
24 newRow["city"] = "HaNoi";
25 newRow["country"] = "Viet Nam";
26 dt.Rows.Add(newRow);
27 // Hiển thị thông tin các rows trong DataSet sau khi thêm vào
28 foreach (DataRow row in dt.Rows)
29 {
30 Literal1.Text = row["firstname"].ToString().PadRight(15) + "|";
31 Literal1.Text += row["lastname"].ToString().PadLeft(15) + "|";
32 Literal1.Text += row["city"];
33 }
34 // Làm việc với Insert
35 SqlCommand cmd = new SqlCommand(ins, conn);
36 cmd.Parameters.Add("@firstname", SqlDbType.NVarChar, 10, "firstname");
37 cmd.Parameters.Add("@lastname", SqlDbType.NVarChar, 20, "lastname");
38 cmd.Parameters.Add("@titleofcourtesy", SqlDbType.NVarChar, 25, "titleofcourtesy");
39 cmd.Parameters.Add("@city", SqlDbType.NVarChar, 15, "city");
40 cmd.Parameters.Add("@country", SqlDbType.NVarChar, 15, "country");
41 // Tiến hành insert vào database Source
42 da.InsertCommand = cmd;
43 da.Update(ds, "employees");
44 }
45 catch (Exception e)
46 {
47 // Bắt lỗi
48 Console.WriteLine(e.Message);
49 }
50 finally
51 {
52 // Đóng kết nối53 conn.Close();
54 }
55 }
Qua ví dụ trên bạn có thể nhận thấy DataSet khá linh hoạt, thông qua việc đổ dữ liệu từ dataSet đến các
Tables, chúng ta có thể xem thông tin, chỉnh sửa thông tin và khi chỉnh sửa xong có thể update cho
DataSource. Nếu các bạn nào tinh ý sẽ thấy quá trình trên thêm vào thực hiện quá dài cứ lập đi lặp lại
việc cmd.Parameters.Add,để giải quyết vấn để này .NET cung cấp cho ta SqlCommandBuilder
Bạn xem ví dụ sau:
01 private void DataSetInsertAndView()
02 {
03 // Tạo connection string
04 string connString = @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=******";
05 // Tạo SQL query
06 string ins = @"INSERT INTO employees (firstname, lastname, titleofcourtesy, city, country) VALUES
07 (@firstname, @lastname, @titleofcourtesy, @city, @country) ";
08 // Tạo connection
09 SqlConnection conn = new SqlConnection(connString);
10 try
11 {
12 // Tạo Adapter13 SqlDataAdapter da = new SqlDataAdapter(qry, conn);
14 // Tạo commandbuider
15 SqlCommandBuilder cb = new SqlCommandBuilder(da);
16 // Tạo và lấp đầy DataSet
17 DataSet ds = new DataSet();
18 da.Fill(ds, "employees");
19 // Lấy thông tin Table vào DataTable
20 DataTable dt = ds.Tables["employees"];
21 // Tạo thêm row mới
22 DataRow newRow = dt.NewRow();
23 newRow["firstname"] = "Pi";
24 newRow["lastname"] = "Pi_Pi";25 newRow["titleofcourtesy"] = "AND";
26 newRow["city"] = "UITS";
27 newRow["country"] = "Viet Nam";
28 dt.Rows.Add(newRow);
29 // Hiển thị thông tin các rows trong DataSet sau khi thêm vào
30 foreach (DataRow row in dt.Rows)
31 {
32 Literal1.Text = row["firstname"].ToString().PadRight(15) + "|";
33 Literal1.Text += row["lastname"].ToString().PadLeft(15) + "|";
34 Literal1.Text += row["city"];
35 }
36 //Nhờ sử dụng SqlCommandBuilder mà ta update rất nhanh37 da.Update(ds, "employees");
38 }
39 catch (Exception e)
40 {
41 // Bắt lỗi
42 Console.WriteLine(e.Message);
43 }
44 finally
45 {
46 // Đóng kết nối47 conn.Close();
48 }
49 }
// Trong hai ví dụ trên mình có tạo 1 <asp:Literal ID="Literal1"
runat="server" /> để khi chạy sẽ hiển thị dữ liệu. Để chạy thử hàm trong
ví dụ trên bạn chỉ cần đưa nó lên hàm Page_Load: DataSetInsertAndView();
3.Tổng kết và So sánh giữa DataSet và DataReader
3.1. DataReader:
-Ưu điểm: Thực thi nhanh, ít tốn tài nguyên hơn so với DataSet rất nhiều
-Khuyết Điểm: Tùy biến không cao, thường dùng để lấy dữ liệu và trình bày,
hạn chế chỉnh sửa CSDL
3.2. DataSet
- Ưu điểm: Tùy biến cao, có thể chỉnh sửa CSDL rất tiện lợi
-Khuyết điểm: Như đã trình bày, hơi tốn tài nguyên
Lời khuyên: Tùy vào từng trườn hợp, từng mục đích mà ta có thể quyết định
chọn cái nào, tránh lạm dụng quá khả năng một cái, phải biết kết hợp hài
hòa. Thông thường khi bạn xuất CSDL viết dưới dạng XML, sau đó thao tác
trên XML thì bạn nên sử dụng DataReader để phát huy sức mạnh của nó.
QUAN HỆ C# VÀ DATABASE :: XÂY DỰNG LỚP THỰC THI LỆNH SQL
Đây chính là lớp thứ nhất (DataAccsess Layer) trong mô hình 3 lớp. Lớp này
có nhiệm vụ thực hiện việc kết nối và thực thi các câu truy vấn dạng
NoneQuery (Câu truy vấn không tra về giá trị - dạng Insert, Update,
Delete), câu truy vấn trả về giá trị. Thực thi các Store Procedure,
Sau khi tạo Project bạn chọn menu File/Add/New Project, Sau đó chọn Class
Library.
Đặt tên cho Project. Khi đó VS sẽ tạo một file mặc định là class1.cs. Bạn có
thể xóa nó đi và tạo một file class mới. Đặt tên cho class này và thực hiện
các hàm sau. Ở đây mình sẽ giới thiệu các hàm cơ bản. Nếu cần bạn có thể
download Class ở liên kết cuỗi bài viết.
+ Hàm mở và đóng kết nối01 public SqlConnection MoKetNoi()
02 {
03 SqlConnection sqlCn = new SqlConnection(ConnectionString);
04 try
05 {
06 sqlCn.Open();
07 }
08 catch
09 {
10 return null;
11 }
12 return sqlCn;13 }
14
15 public void DongKetNoi(SqlConnection sqlCn)
16 {
17 if (sqlCn != null)
18 {
19 if (sqlCn.State == ConnectionState.Open)
20 sqlCn.Close();
21 sqlCn.Dispose();
22 }
23 }
+ Hàm thực thi câu truy vấn không dạng Insert Update, Delete
01 /// <summary>
02 ///Thực thi 1 câu lệnh SQL dạng select không trả lại giá trị
03 /// </summary>
04 public string ThucThiLenhSQL(string strSQL)
05 {
06 SqlCommand sqlCommand = new SqlCommand();07 sqlCommand.CommandTimeout = 2000;
08 sqlCn = MoKetNoi();
09 sqlCommand.Connection = sqlCn;10 sqlCommand.Parameters.Clear();
11 sqlCommand.CommandText = strSQL;
12 sqlCommand.CommandType = CommandType.Text;13 try
14 {
15 intErrorNumber = sqlCommand.ExecuteNonQuery();
16 mErrorCode = 0;
17 mErrorMsg = "";
18 DongKetNoi(sqlCn);
19 }
20 catch (SqlException ex)
21 {
22 intErrorNumber = ex.Number;
23 mErrorMsg = ex.Message;
24 System.Console.Write(ex.StackTrace);
25 }
26 finally
27 {
28 if (sqlCn.State == ConnectionState.Open)29 sqlCn.Close();
30 sqlCn.Dispose();
31 }
32 return mErrorCode.ToString() + ":" + mErrorMsg;33 }
+ Hàm thực thi câu truy vấn trả về một DataSet
01 /// <summary>
02 ///Thực thi 1 câu lệnh SQL dạng select có trả về dữ liệu là DataSet
03 /// </summary>
04 public DataSet ThucThiCauTruyVan_TraVeDataSet(string strSQL)
05 {
06 SqlDataAdapter Adapter = new SqlDataAdapter(strSQL, sqlCn);
07 DataSet ds = new DataSet();
08 try
09 {
10 Adapter.Fill(ds);11 DongKetNoi(sqlCn);
12 }
13 catch (SqlException E)
14 {
15 string strDescriptionError = E.Message;
16 }
17 return ds;
18 }
+ Hàm thực thi câu truy vấn có trả về dữ liệu là một bảng
01 /// <summary>
02/// Thực thi 1 câu lệnh SQL dạng select có trả về dữ liệu là 1 bảng
03 /// </summary>
04 /// <return>
05 /// DataTable
06 /// </return>>07 public DataTable ThucThiCauTruyVan_TraVeBang(string strSQL)
08 {
09 sqlCn = MoKetNoi();
10 SqlDataAdapter Adapter = new SqlDataAdapter(strSQL, sqlCn);
11 DataTable ds = new DataTable();
12 try
13 {
14 Adapter.Fill(ds);15 DongKetNoi(sqlCn);
16 }
17 catch (SqlException E)
18 {
19 string strDescriptionError = E.Message;
20 }
21 finally
22 {
23 if (sqlCn.State == ConnectionState.Open)
24 sqlCn.Close();
25 sqlCn.Dispose();
26 }
27 return ds;
28 }
+ Hàm thực thi 1 StoreProcedure không trả lại giá trị
01 /// <summary>
02 /// Thực thi 1 StoreProcedure không trả lại giá trị
03 /// </summary>
04 protected void ThucThiStore(05 string TenStoreProcedure,
06 SqlParameter[] sqlParam)
07 {
08 try
09 {
10 SqlCommand sqlCmd = new SqlCommand();11 sqlCmd.CommandTimeout = 2000;
12 sqlCn = MoKetNoi();
13 sqlCmd.Connection = sqlCn;
14 sqlCmd.CommandType = CommandType.StoredProcedure;
15 sqlCmd.CommandText = TenStoreProcedure;
16 for (int i = 0; i < sqlParam.Length; i++)
17 {
18 sqlCmd.Parameters.Add(sqlParam[i]);
19 }
20 sqlCmd.ExecuteNonQuery();21 DongKetNoi(sqlCn);
22 }
23 catch (SqlException sqlEx)
24 {
25 strErrorMessage = sqlEx.Message;
26 intErrorNumber = sqlEx.Number;
27 }
28 finally
29 {
30 if (sqlCn.State == ConnectionState.Open)31 sqlCn.Close();
32 sqlCn.Dispose();
33 }
34 }
+ Hàm thực thi Store trả về dữ liệu là 1 Dataset
01 /// <summary>
02 /// Thực thi Store trả về dữ liệu là 1 Dataset
03 /// </summary>
04 /// <param name="TenStoreProcedure"></param>05 /// <param name="sqlParam"></param>
06 /// <returns></returns>
07 protected DataSet ThucThiStoreTraVeDataSet(
08 string TenStoreProcedure,
09 SqlParameter[] sqlParam)
10 {
11 DataSet dtbTmp = new DataSet();
12 try
13 {
14 sqlCn = MoKetNoi();15 SqlCommand sqlCmd = new SqlCommand();
16 sqlCmd.CommandTimeout = 2000;
17 sqlCmd.Connection = sqlCn;
18 sqlCmd.CommandType = CommandType.StoredProcedure;
19 sqlCmd.CommandText = TenStoreProcedure;
20 for (int i = 0; i < sqlParam.Length; i++)
21 {
22 sqlCmd.Parameters.Add(sqlParam[i]);
23 }
24 SqlDataAdapter sqlDA = new SqlDataAdapter();25 sqlDA.SelectCommand = sqlCmd;
26 sqlDA.Fill(dtbTmp);
27 DongKetNoi(sqlCn);
28 }
29 catch (SqlException sqlEx)
30 {
31 strErrorMessage = sqlEx.Message;
32 intErrorNumber = sqlEx.Number;
33 }
34 finally
35 {
36 if (sqlCn.State == ConnectionState.Open)37 sqlCn.Close();
38 sqlCn.Dispose();
39 }
40 return dtbTmp;41 }
+ Thực thi 1 StoreProcedure có trả về dữ liệu là 1 bảng
view source
print ?
01 /// <summary>
02 /// Thực thi 1 StoreProcedure có trả về dữ liệu là 1 bảng03 /// </summary>
04 /// <return>
05 /// DataTable
06 /// </return>>07 protected DataTable ThucThiStoreTraVeBang(
08 string TenStoreProcedure,
09 SqlParameter[] sqlParam)
10 {
11 DataTable dtbTmp = new DataTable();
12 try
13 {
14 sqlCn = MoKetNoi();15 SqlCommand sqlCmd = new SqlCommand();
16 sqlCmd.CommandTimeout = 2000;
17 sqlCmd.Connection = sqlCn;
18 sqlCmd.CommandType = CommandType.StoredProcedure;
19 sqlCmd.CommandText = TenStoreProcedure;
20 for (int i = 0; i < sqlParam.Length; i++)
21 {
22 sqlCmd.Parameters.Add(sqlParam[i]);
23 }
24 SqlDataAdapter sqlDA = new SqlDataAdapter();25 sqlDA.SelectCommand = sqlCmd;
26 sqlDA.Fill(dtbTmp);
27 DongKetNoi(sqlCn);
28 }
29 catch (SqlException sqlEx)
30 {
31 strErrorMessage = sqlEx.Message;
32 intErrorNumber = sqlEx.Number;
33 }
34 finally
35 {
36 if (sqlCn.State == ConnectionState.Open)37 sqlCn.Close();
38 sqlCn.Dispose();
39 }
40 return dtbTmp;41 }