You are on page 1of 165

Tập bài giảng Lập trình cơ sở dữ liệu

MỤC LỤC
CHƯƠNG 1. LẬP TRÌNH CƠ SỞ DỮ LIỆU SỬ DỤNG ADO.NET 1
1.1. Tạo kết nối 1
1.1.1. Tạo chuỗi kết nối 1
1.1.2. Tạo đối tượng kết nối 1
1.2. Thêm dữ liệu 1
1.3. Xóa dữ liệu 2
1.4. Sửa dữ liệu 2
1.5. Tìm kiếm thông tin 2
1.6. Xây dựng truy vấn sử dụng tham số 2
1.7. Ví dụ 3
CHƯƠNG 2: LẬP TRÌNH CƠ SỞ DỮ LIỆU SỬ DỤNG LINQ to SQL 18
2.1. Giới thiệu về LINQ 18
2.2. Cú pháp LINQ 18
2.3. Các toán tử truy vấn LINQ 22
2.4. Mô hình LINQ to SQL 32
2.4.1. Khái niệm 32
2.4.2. Các lớp thực thể và DataContext 32
2.4.3. Thiết kế mô hình LINQ to SQL 33
2.5. Truy vấn cơ sở dữ liệu sử dụng LINQ to SQL 37
2.5.1. Đối tượng DataContext 37
2.5.2. Khai báo thực thể 38
2.5.3. Lấy thuộc tính của thực thể 38
2.6. Làm việc với cơ sở dữ liệu sử dụng LINQ to SQL 38
2.6.1. Thêm dữ liệu 38
2.6.2. Xóa dữ liệu 39
2.6.3. Tìm kiếm thông tin 39
2.6.4. Sửa dữ liệu 40
2.6.5. Các ví dụ 41
2.7. Sử dụng LINQ to SQL kết hợp với Stored Procedure 49
2.7.1. Đưa Stored Procedure vào mô hình LINQ to SQL 49
2.7.2. Thêm dữ liệu 49
2.7.3. Xóa dữ liệu 50
2.7.4. Tìm kiếm thông tin 50
2.7.5. Sửa dữ liệu 51
i
Tập bài giảng Lập trình cơ sở dữ liệu
2.7.6. Các ví dụ 51
CHƯƠNG 3: LT CSDL SỬ DỤNG ADO.NET ENTITY DATA MODEL 55
3.1. Mô hình Entity Data Model (EDM) 55
3.1.1. Các khái niệm 55
3.1.2. Các thành phần của mô hình EDM 57
3.1.3. Ánh xạ giữa tập thực thể với bảng hoặc view 58
3.2. Thiết kế mô hình EDM bằng công cụ Designer 59
3.2.1. Tạo mới mô hình EDM 59
3.2.2. Thêm mới, xóa một tập thực thể 60
3.2.3. Thêm, sửa, xóa, các thuộc tính 62
3.2.4. Thêm, sửa, xóa các mối liên hệ 64
3.3. Thiết kế mô hình EDM bằng công cụ Wizard 66
3.4. Cập nhật mô hình EDM từ cơ sở dữ liệu 69
3.5. Sinh cơ sở dữ liệu từ mô hình EDM 71
3.6. Truy vấn cơ sở dữ liệu sử dụng EDM 74
3.6.1. Khai báo đối tượng EDM 74
3.6.2. Tham chiếu đến phương thức và thuộc tính đối tượng EDM 75
3.6.3. Khai báo thực thể 75
3.6.4. Lấy thuộc tính của thực thể 75
3.6.5. Lớp DBContext 75
3.7. Làm việc với cơ sở dữ liệu sử dụng EDM 76
3.7.1. Các cách thức truy vấn với EDM 76
3.7.2. Thêm dữ liệu 77
3.7.3. Xóa dữ liệu 78
3.7.4. Tìm kiếm thông tin 78
3.7.4. Sửa dữ liệu 79
3.7.5. Các ví dụ 80
3.8. Sử dụng EDM kết hợp với Stored Procedure 87
3.8.1. Đưa Stored Procedure vào mô hình EDM 87
3.8.2. Ánh xạ Stored Procedure cho tập thực thể trong mô hình EDM 89
3.8.3. Thêm dữ liệu 90
3.8.4. Sửa dữ liệu 90
3.8.5. Xóa dữ liệu 91
3.8.6. Tìm kiếm thông tin 91
3.8.7. Ví dụ 92

ii
Tập bài giảng Lập trình cơ sở dữ liệu
CHƯƠNG 4: THIẾT KẾ BÁO CÁO BẰNG CRYSTAL REPORT 96
4.1. Giới thiệu Crystal Report 96
4.2. Thiết kế Report bằng công cụ Wizard 96
4.3. Thiết kế Report bằng công cụ Designer 102
4.3.1. Tạo mới file Report 102
4.3.2. Đưa các đối tượng vào Report 103
4.3.3. Chọn dữ liệu nguồn cho Report 103
4.3.4. Đưa các trường vào Report 104
4.3.5. Làm việc với nhóm (Group) 104
4.3.6. Sắp xếp thông tin (Record Sort) 106
4.3.7. Làm việc với trường tổng hợp (Summary) 106
4.3.8. Làm việc với Fomular Fields 108
4.3.9. Đưa các trường có sẵn vào Report 108
4.3. Xem Report 109
4.5. Tích hợp Report vào ứng dụng 109
4.5.1. Tạo môi trường tích hợp 109
4.5.2. Tích hợp report vào Form 109
4.5.3. Lập trình tích hợp Report vào Form 110
4.6. Ví dụ 111
CHƯƠNG 5: PHÂN PHỐI VÀ ĐÓNG GÓI ỨNG DỤNG 117
5.1. Lập kế hoạch triển khai đóng gói dự án 117
5.1.1. Thiết kế Form chủ 117
5.1.2. Liên kết các Form lên Form chủ 118
5.2. Các cách đóng gói và triển khai ứng dụng khác nhau 118
5.3. Tạo dự án Deployment 119
5.4. Tùy biến các lựa chọn đóng gói 119
5.4.1. Cấu hình các thiết lập 119
5.4.2. Tạo shortcut cho ứng dụng cài đặt 122
5.4.3. Thiết lập các thuộc tính chương trình 123
5.4.4. Đặt các thuộc tính cho gói ứng dụng 124
5.5. Biên dịch, đóng gói dự án và kiểm tra việc tạo file cài đặt 125
5.6. Cài đặt, tìm hiểu các file Setup và gỡ chương trình 126
5.6.1. Cài đặt chương trình 126
5.6.2. Tháo gỡ chương trình 128

iii
Tập bài giảng Lập trình cơ sở dữ liệu
LỜI NÓI ĐẦU
Mỗi chương trong tập bài giảng đều hệ thống hóa các kiến thức cơ bản, cần thiết.
Tương ứng với mỗi nội dung kiến thức đều có các ví dụ minh họa cụ thể, gắn với các
ứng dụng thực tiễn. Trong bài giảng sử dụng cơ sở dữ liệu của một hệ thống quản lý
kinh doanh để xây dựng các ứng dụng minh họa. Cơ sở dữ liệu quản lý kinh doanh
(QLKD) gồm các bảng sau:
tbHANG(Mahang, Tenhang, DVT): Chứa thông tin của các mặt hàng
tbKHACH(Makh ,Tenkh, DCKH): Chứa thông tin của các khách hàng
tbNCC(Mancc, Tenncc, DiachiNCC): Chứa thông tin của các nhà cung cấp
tbPN(SoPN, NgayN, Mancc): Chứa thông tin về số phiếu nhập
tbPX(SoPX, NgayX, Makh): Chứa thông tin về số phiếu xuất
tbCTPN(SoPN, Mahang, SLN, DGN): Chứa thông tin chi tiết về số phiếu nhập
tbCTPX(SoPX, Mahang, SLX, DGX): Chứa thông tin chi tiết về số phiếu xuất
Trong đó: Mahang-Mã mặt hàng, Tenhang-Tên mặt hàng, DVT-Đơn vị tính Makh-
Mã khách hàng, Tenkh-Tên khách hàng, DCKH-Địa chỉ, Mancc-Mã nhà cung cấp,
Tenncc-Tên nhà cung cấp, DiachiNCC- Địa chỉ nhà cung cấp, SoPN-Số phiếu nhập,
NgayN-Ngày nhập hàng, SoPX-Số phiếu xuất, NgayX-Ngày xuất hàng, SLN-Số lượng
nhập, DGN-Đơn giá nhập, SLX-Số lượng xuất, DGX-Đơn giá xuất.

iv
Tập bài giảng Lập trình cơ sở dữ liệu

CHƯƠNG 1. LẬP TRÌNH CƠ SỞ DỮ LIỆU SỬ DỤNG ADO.NET


1.1. Tạo kết nối
Khi xây dựng một đối tượng SqlConnection, cần chỉ định một chuỗi kết nối
(Connection Strings) như một tham số, chuỗi kết nối chứa tất cả các thông tin cần thiết
để mở một kết nối tới cơ sở dữ liệu. Để xây dựng chuỗi kết nối có hai cách: dùng file
config hoặc code trực tiếp
1.1.1. Tạo chuỗi kết nối
a. Dùng file .config
Thực hiện các bước sau để thực hiện tạo kết nối dùng file .config:
Bước 1: Kích chuột phải chọn project QLKD_ADO trong cửa sổ Solution Explorer,
lựa chọn mục Properties từ cửa sổ hiện ra.
Bước 2: Trong cửa sổ Properties của project QLKD_ADO chọn mục Settings
Bước 3: Tạo kết nối tới một cơ sở dữ liệu
- Thêm một mục mới trong cửa sổ Settings
- Gán giá trị cho các thuộc tính
+ Name = “ConnectionString”
+ Type = (ConnectionString)
+ Scope = Application
+ Value: Kích chọn vào nút /Thiết lập chuỗi kết nối

Hình 1.1. Tạo chuỗi kết nối tới một cơ sở dữ liệu


Bước 4: Tạo biến chuỗi kết nối
string <Connection_String> = Properties.Settings.Default.
ConnectionString;
b) Dùng trực tiếp trên code của form
Cú pháp:
- Cách 1:
string <Connection_String>= “Server=<Server_Name>;
Database=<Database_Name>;
Integrated Security=<True/False>;
UserName=<User_Name>;
Password=<Password>”;
- Cách 2:
string <Connection String> = “Server=<Server_Name>;
Database=<Database_Name>;
Integrated Security=<True/False>;
UserName=<User_Name>;
Password=<Password>”;
1.1.2. Tạo đối tượng kết nối
SqlConnection <SqlConnection_Name> = new SqlConnection (<Connection
String>);
1.2. Thêm dữ liệu
Để thêm bản ghi vào một bảng trong cơ sở dữ liệu nguồn (SQL Server) có thể thực
hiện các bước sau:
Bước 1: Viết câu lệnh SQL

1
Tập bài giảng Lập trình cơ sở dữ liệu

string <SQL_Command> = "INSERT INTO <Table_Name> [( <Fields> )]


VALUES (<Inserted_Record>)";
Bước 2: Tạo đối tượng SqlCommand
SqlCommand <SqlCommand_Name> = new SqlCommand(<SQL_Command>,
<SqlConnection_Name>);
Bước 3: Thực thi câu lệnh SQL
<SqlCommand_Name>.ExecuteNoneQuery();
1.3. Xóa dữ liệu
Để xóa bản ghi trong một bảng cơ sở dữ liệu nguồn (SQL Server) có thể thực hiện
các bước sau:
Bước 1: Viết câu lệnh SQL
string <SQL_Command> = "DELETE FROM <Table_Name> [WHERE
<Search_Condition>]";
Bước 2: Tạo đối tượng SqlCommand
SqlCommand <SqlComman_Name> = new SqlCommand(<SQL_Command>,
<SqlConnection_Name>);
Bước 3: Thực thi truy vấn SQL_Command
<SqlCommand_Name>.ExecuteNoneQuery();
1.4. Sửa dữ liệu
Để sửa bản ghi trong một bảng cơ sở dữ liệu nguồn (SQL Server) có thể thực hiện
các bước sau:
Bước 1: Viết câu lệnh SQL
string <SQL_Command> = "UPDATE <Table_Name> SET <Column_Name = Value>
[WHERE <Search_Condition>]";
Bước 2: Tạo đối tượng SqlCommand
SqlCommand <SqlCommand_Name> = new SqlCommand(<SQL_Command>,
<SqlConnection_Name>);
Bước 3: Thực thi truy vấn SQL_Command
<SqlCommand_Name>.ExecuteNoneQuery();
1.5. Tìm kiếm thông tin
Bước 1: Viết câu lệnh SQL
string <SQL_Command> = "SELECT [  <Fields  Expression>]FROM
<Table_Name> WHERE <Search_Condition>";
Bước 2: Tạo đối tượng SqlCommand
SqlCommand <SqlCommand_Name> = new SqlCommand(<SQL_Command>,
<SqlConnection_Name>);
Bước 3: Thực thi truy vấn SQL_Command và trả về đối tượng SqlDataReader
SqlDataReader <DataReader_Name> = new SqlDataReader();
<DataReader_Name> = <SqlCommand_Name>.ExecuteReader();
Bước 4: Hiển thị kết quả tìm thấy
- Đưa dữ liệu lên DataGridView
<DataTable_Name>.Load(<DataReader_Name>);
<DataGridView Name>.DataSource= <DataTable_Name>;
- Đưa dữ liệu lên TextBox
<TextBox Name>.Text = <DataReader_Name>.GetString(<Column_Index>);
1.6. Xây dựng truy vấn sử dụng tham số
Mục đích của việc sử dụng tham số là giúp cho câu lệnh truy vấn trở nên tổng quát
hơn và có thể sử dụng nhiều lần với các giá trị khác nhau. Sử dụng truy vấn tham số bao
gồm các bước sau:
Bước 1: Xây dựng câu lệnh truy vấn SQL có chứa tham số

2
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 2: Tạo đối tượng SqlCommand


SqlCommand <SqlCommand_Name> = new SqlCommand(<SQL_Command>,
<SqlConnection_Name>);
Bước 3: Thêm tham số vào đối tượng SqlCommand.
<SqlCommand_Name>.Parameters.Add(“@<Tên tham số>“,<Giá trị>);
Bước 4: Thực thi truy vấn.
Ví dụ: Thêm bản ghi mới với bảng tbHang trong cơ sở dữ liệu QLKD.
string strCn = “Server= NTV\NTV; Database=QLYBH; Integrated
Security=True”;
SqlConnection cn = new SqlConnection(strCn);
cn.Open();
string sql = “INSERT INTO tblMatHang (Mahang, Tenhang , DVT)
VALUES(@Mahang, @Tenhang, @DVT)”;
SqlCommand cmd = new SqlCommand(sql, cn);
cmd.Parameters.Add(“@Mahang”, “MH012”);
cmd.Parameters.Add(“@Tenhang”,“Máy tính”);
cmd.Parameters.Add(“DVT”,“Cái”);
cmd.ExecuteNonQuery();
cn.Close();
1.7. Ví dụ
Ví dụ 1.1: Form quản lý danh mục các mặt hàng có mẫu sau. Hãy lập trình để thực
hiện việc thêm, hiệu chỉnh, xóa, tìm kiếm thông tin các mặt hàng.

Hình 1.2. Giao diện form quản lý mặt hàng


Bước 1: Tạo và thiết kế Form Quản lý danh mục các mặt hàng
STT Đối tượng Thuộc tính Giá trị
Name frm_MH
1 Form Text Quản lý danh mục các mặt
hàng
2 Label Text Mã mặt hàng
3 Label Text Tên mặt hàng
4 Label Text Đơn vị tính
5 GroupBox Text Thông tin mặt hàng
6 GroupBox Text Danh sách mặt hàng
7 TextBox Name txtMaMH
8 TextBox Name txtTenMH
3
Tập bài giảng Lập trình cơ sở dữ liệu

STT Đối tượng Thuộc tính Giá trị


9 TextBox Name txtDVT
10 DataGridView Name dgvMatHang
Name btnThem
11 Button
Image System.Drawing.Bitmap
Name btnHieuchinh
12 Button
Image System.Drawing.Bitmap
Name btnLuu
13 Button
Image System.Drawing.Bitmap
Name btnXoa
14 Button
Image System.Drawing.Bitmap
Name btnTimkiem
15 Button
Image System.Drawing.Bitmap
Bước 2: Khai báo không gian tên
using System.Data.SqlClient;
Bước 3: Khai báo các biến và đối tượng
int iu;//iu = 0 ứng với lựa chọn thêm mới hoặc iu= 1 ứng với hiệu
chỉnh
SqlConnection cn;
Bước 4: Lập trình các phương thức
1) Phương thức hiện thị trên lưới
private void Show_GridView()
{
try
{
string sql = "select * from tbHang";
SqlCommand cm = new SqlCommand(sql, cn);
cn.Open();
SqlDataReader reader = cm.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
dg_Hienthi.DataSource = dt;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,"Thông báo");
}
finally
{
cn.Close();
}
}
2) Phương thức làm trắng các TextBox
private void Set_Empty()
{
txtMaMH.Text = "";
txtTenMH.Text = "";
txtDVT.Text = "";
}
Bước 5: Lập trình sự kiện các điều khiển
1) Lập trình sự kiện Click của nút Thêm
4
Tập bài giảng Lập trình cơ sở dữ liệu

private void btnThem_Click(object sender, EventArgs e)


{
iu = 0;
Set_Empty();
btnLuu.Enabled = true;
btnThem.Enabled = false;
}
2) Lập trình sự kiện Click của nút Hiệu chỉnh
private void btnHieuchinh_Click(object sender, EventArgs e)
{
iu = 1;
btnLuu.Enabled = true;
btnHieuchinh.Enabled = false;
}
3) Lập trình sự kiện Click của nút Xóa
private void btnXoa_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
string str = "OK";
try
{
string sql = "delete from tbHang where maMH = " +
txtMaMH.Text;
SqlCommand cm = new SqlCommand(sql, cn);
cn.Open();
cm.ExecuteNonQuery();
}
catch(Exception ex)
{
str = ex.Message;
}
finally
{
cn.Close();
if (str == "OK")
{
MessageBox.Show("Xóa thành công", "Thông báo");
Show_GridView();
}
else MessageBox.Show("Không xóa được dữ liệu",
"Thông báo");
}
}
}
4) Lập trình sự kiện Click của nút Lưu
private void btnLuu_Click(object sender, EventArgs e)
{
btnLuu.Enabled = false;
btnThem.Enabled = true;
btnHieuchinh.Enabled = true;
if (txtMaMH.Text != "" && txtTenMH.Text != "" && txtDVT.Text
!= "" )

5
Tập bài giảng Lập trình cơ sở dữ liệu

{
string sql = "";
string str = "OK";
if (iu == 0) sql = "insert into tbHang
(MaMH,Tenmathang,Dvt) values(txtMaMH.Text + "',N'" + txtTenMH.Text + "',N'"
+ txtDVT.Text + "')";
else sql = "update tbHang set Tenhang = N'" +
txtTenMH.Text + "',Dvt = N'" + txtDVT.Text + "' where MaMH = " +
txtMaMH.Text;
try
{
SqlCommand cm = new SqlCommand(sql, cn);
cn.Open();
cm.ExecuteNonQuery();
}
catch (Exception ex)
{
str = ex.Message;
}
finally
{
cn.Close();
if(str =="OK")
{

if (iu == 0) MessageBox.Show("Thêm mới thành


công", "Thông báo");
else MessageBox.Show("Cập nhật dữ liệu thành
công", "Thông báo");
Show_GridView();
}
else MessageBox.Show(str, "Thông báo");
}
}
}
5) Lập trình sự kiện Click nút Tìm kiếm
private void btnTimkiem_Click(object sender, EventArgs e)
{
try
{
string sql = "select * from tbHang where maMH = " +
txtMaMH.Text;
SqlCommand cm = new SqlCommand(sql, cn);
cn.Open();
SqlDataReader reader = cm.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
dg_Hienthi.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Thông báo");
}
finally
{
6
Tập bài giảng Lập trình cơ sở dữ liệu

cn.Close();
}
}
6) Lập trình sự kiện SelectionChanged của DataGridView
private void dg_Hienthi_SelectionChanged(object sender, EventArgs e)
{
if (dg_Hienthi.SelectedRows.Count > 0)
{
txtMaMH.Text = dg_Hienthi.CurrentRow.Cells[0].Value.ToString();
txtTenMH.Text= dg_Hienthi.CurrentRow.Cells[1].Value.ToString();
txtDVT.Text = dg_Hienthi.CurrentRow.Cells[2].Value.ToString();
}
}

Ví dụ 1.2: Xây dựng Form quản lý bán hàng có mẫu sau:

Hình 1.3. Form quản lý xuất hàng.


Bước 1: Tạo lớp DBAccesc thực hiện truy vấn, cập nhật, thêm, sửa, xóa dữ liệu.
class DBAccess
{
#region 1. Khai báo các thành viên dữ liệu
//khai báo đối tượng kết nối
SqlConnection conn;
//khai báo đối tượng command để thực hiện các câu lệnh truy vấn
SqlCommand cmd;
#endregion
#region 2. Các phương thức khởi tạo
public DBAccess()
7
Tập bài giảng Lập trình cơ sở dữ liệu

{
//Khai báo xâu kết nối sử dụng xâu kết nối được cấu hình
trong app.config
string conStr =
Properties.Settings.Default.ConnectionString;
//tạo đối tượng kết nối
conn = new SqlConnection(conStr);
}
#endregion
#region 3. Các phương thức thao tác với CSDL
// Phương thức mở kết nối tới CSDL
private void Open()
{
if (conn.State == System.Data.ConnectionState.Closed)
conn.Open();
}
// Phương thức ngắt kết nối với CSDL
private void Close()
{
if (conn.State == System.Data.ConnectionState.Open)
conn.Close();
}
public object GetValue(string query)
{
//mở kết nối đến cơ sở dữ liệu
Open();
//tạo câu lệnh truy vấn
cmd = new SqlCommand(query, conn);
//thực hiện câu lệnh truy vấn trả về một đối tượng
return cmd.ExecuteScalar();
}
//phương thức lấy giá trị từ mệnh đề select trả về một bảng
trong bộ nhớ
public DataTable GetTable(string select)
{
//mở kết nối đến cơ sở dữ liệu
Open();
//tạo câu lệnh truy vấn
cmd = new SqlCommand(select, conn);
//Thực hiện truy vấn trả về đối tượng reader
SqlDataReader reader = cmd.ExecuteReader();
//tạo một bảng dữ liệu mới trong bộ nhớ
DataTable dt = new DataTable();
//lấy dữ liệu đổ vào bảng
dt.Load(reader);
//trả về bảng
return dt;
}
//phương thức thực thi một câu lệnh truy vấn sql (insert,
update, delete..)
public int ExecuteNonQuery(string query)
{
//mở kết nôi đến csdl
Open();

8
Tập bài giảng Lập trình cơ sở dữ liệu

//tạo đối tượng sqlcommand chứa xâu truy vấn, đến kết nối
hiện hành
cmd = new SqlCommand(query, conn);
//thực thi câu lệnh sql
return cmd.ExecuteNonQuery();
}
//Khai báo phương thức thêm bản ghi bằng phương thức
ExecuteNonQuery với các tham trị là mảng tham số và mảng giá trị tương ứng
với các tham số.
public int ExecuteNonQuery(int op, string strTable, string[]
strField, string[] strPara, object[] strValue)
{
Open();
//Khai báo đối tượng SqlParameter
SqlParameter para;
String strSQL;
cmd = new SqlCommand();
cmd.Connection = conn;
switch(op)
{
case 1:
strSQL = "insert into " + strTable + " (";
for (int i = 0; i < strPara.Length; i++)
{
strSQL += strField[i] + ",";
}
strSQL = strSQL.Substring(0,strSQL.Length-1) + ")
values(";
for (int i = 0; i < strPara.Length; i++)
{
strSQL += strPara[i] + ",";
para = new SqlParameter(strPara[i],
strValue[i]);
cmd.Parameters.Add(para);
}
strSQL = strSQL.Substring(0,strSQL.Length-1) + ")";
break;
case 2:
strSQL = "update " + strTable + " set ";
for (int i = 1; i < strPara.Length; i++)
{
strSQL += strField[i] + "=" + strPara[i] +
"," ;
para = new SqlParameter(strPara[i],
strValue[i]);
cmd.Parameters.Add(para);
}
strSQL = strSQL.Substring(0, strSQL.Length - 1);
strSQL += " where " + strField[0] + "=" +
strPara[0];
para = new SqlParameter(strPara[0], strValue[0]);
cmd.Parameters.Add(para);
break;
case 3:
strSQL = "delete from " + strTable + " where ";
9
Tập bài giảng Lập trình cơ sở dữ liệu

for (int i = 0; i < strPara.Length; i++)


{
strSQL += strField[i] + "=" + strPara[i] + "
and ";
para = new SqlParameter(strPara[i],
strValue[i]);
cmd.Parameters.Add(para);
}
strSQL = strSQL.Substring(0, strSQL.Length - 4);
break;
default:
return -1;
}
cmd.CommandText = strSQL;
return cmd.ExecuteNonQuery();
}
//Khai báo phương thức lấy giá trị từ bảng dữ liệu đưa vào đối
tượng DataTable có tham số
public DataTable GetTable(string strTable , string[] strField
,string[] strPara , object[] strValue)
{
SqlParameter para;
string strSQL;
strSQL = "Select * from " + strTable + " where ";
for(int i = 0;i < strPara.Length; i++)
{
strSQL += strField[i] + "=" + strPara[i] + " and ";
para = new SqlParameter(strPara[i], strValue[i]);
cmd.Parameters.Add(para);
}
strSQL = strSQL.Substring(0, strSQL.Length - 4);
cmd.CommandText = strSQL;
DataTable dt = new DataTable();
SqlDataReader reader = cmd.ExecuteReader();
dt.Load(reader);
return dt;
}
#endregion
}
Bước 2: Tạo và thiết kế Form Quản lý các nhà cung cấp mặt hàng
STT Đối tượng Thuộc tính Giá trị
Name frmBanHang
1 Form
Text Quản lý Xuất hàng
2 Label Text Số phiếu
3 Label Text Mã khách hàng
4 Label Text Ngày xuất
5 GroupBox Text Thông tin phiếu xuất hàng
6 GroupBox Text Danh sách hàng xuất
7 TextBox Name txtTenKH
8 DateTimePicker Name dtp_ngayx
9 ComBoBox Name cbbSPXuat
10 ComBoBox Name cbbMaKH
10
Tập bài giảng Lập trình cơ sở dữ liệu

11 DataGridView Name dgv_hangx


Name btThem
12 Button
Text Thêm
Name btSua
13 Button
Text Sửa
Name btXoa
14 Button
Text Xóa
Name btLuu
15 Button
Text Lưu
Name btLuuCTBH
16 Button
Text Lưu Chi tiết bán hàng
Name btXoaCTBH
17 Button
Text Xóa Chi tiết Bán hàng
Bước 3: Khai báo một số đối tượng và biến
int iu;
int count;//Đếm số bản ghi đã có theo SoPX trong bảng tbCTPX
DBAccess dba;
int index;//chỉ số mục được chọn trong ComboboxSoPX
Bước 4: Lập trình một số phương thức sau:
1) Phương thức nạp dữ liệu ComBoBox ComboBoxSoPX
private void LoadComboBoxSoPX()
{
cbbSPXuat.DataSource = dba.GetTable("select * from tbPX");
cbbSPXuat.DisplayMember = "SoPX";
cbbSPXuat.SelectedIndex = index;
}
2) Phương thức nạp dữ liệu ComBoBox cbbMaKH
private void LoadComboBoxMaKH()
{
cbbMaKH.DataSource = dba.GetTable("select * from tbKhach");
cbbMaKH.DisplayMember = "MaKH";
}
3) Phương thức làm trắng các điều khiển khi kích vào nút Thêm
private void SetEmpty()
{
cbbSPXuat.Text = "";
dtp_ngayx.Value = DateTime.Now;
}
4) Phương thức tạo các cột của DataGridView
public void CreateGridviewColumn(DataGridView grv)
{
//Thêm cột thứ tự
DataGridViewTextBoxColumn stt = new
DataGridViewTextBoxColumn();
stt.Name = "STT";
stt.DataPropertyName = "STT";
stt.HeaderText = "STT";
stt.ReadOnly = true;
grv.Columns.Add(stt);
//Thêm cột số phiếu xuất

11
Tập bài giảng Lập trình cơ sở dữ liệu

DataGridViewTextBoxColumn sopx = new


DataGridViewTextBoxColumn();
sopx.Name = "SoPX";
sopx.DataPropertyName = "SoPX";
sopx.HeaderText = "Phiếu xuất";
sopx.ReadOnly = true;
grv.Columns.Add(sopx);
//Thêm cột comboBox
DataGridViewComboBoxColumn cb = new
DataGridViewComboBoxColumn();
DataTable dtMH = dba.GetTable("select * from tbHang");
cb.DataSource = dtMH;
cb.Name = "Mahang";
cb.HeaderText = "Mặt hàng";
cb.DataPropertyName = "Mahang";
cb.ValueMember = "Mahang";
cb.DisplayMember = "TenHang";
grv.Columns.Add(cb);
//Thêm cột số lượng
DataGridViewTextBoxColumn soluong = new
DataGridViewTextBoxColumn();
soluong.Name = "SLX";
soluong.DataPropertyName = "SLX";
soluong.HeaderText = "Số lượng";
grv.Columns.Add(soluong);
//Thêm cột đơn giá
DataGridViewTextBoxColumn dongia = new
DataGridViewTextBoxColumn();
dongia.Name = "DGX";
dongia.DataPropertyName = "DGX";
dongia.HeaderText = "Đơn giá";
grv.Columns.Add(dongia);
}
4) Phương thức tải dữ liệu lên DataGridView
public void LoadGridView(DataGridView TenGridView)
{
DataTable dt = dba.GetTable("select * from tbCTPX where SoPX
= N'" + cbbSPXuat.Text + "'");
dgv_hangx.Rows.Clear();
foreach (DataRow ctbh in dt.Rows)
{
dgv_hangx.Rows.Add(ctbh[0], ctbh[1], ctbh[2],
ctbh[3], ctbh[4]);
}
}
5) Phương thức thiết lập vô hiệu hóa các điều khiển
public void SetControl(bool flag)
{
dtp_ngayx.Enabled = flag;
cbbMaKH.Enabled = flag;
btLuu.Enabled = flag;
btThem.Enabled = !flag;
btSua.Enabled = !flag;
if (iu == 0)

12
Tập bài giảng Lập trình cơ sở dữ liệu

{
cbbSPXuat.DropDownStyle = ComboBoxStyle.Simple;
}
}
6) Phương thức cập nhật thông tin chi tiết hóa đơn từ DataGridView
public void UpdateDataGridView_Table()
{
string SoPX = cbbSPXuat.Text;
string Mahang;
float slx;
float dgx;
string stt;
string[] strField = { "SoTT", "SoPX", "MaHang", "SLX", "DGX"
};
string[] strPara = { "@SoTT", "@SoPX", "@MaHang", "@SLX",
"@DGX" };
try
{
//duyệt từng hàng trên gridview
for (int i = 0; i < count - 1; i++)
{
stt =
dgv_hangx.Rows[i].Cells["STT"].Value.ToString();
Mahang =
dgv_hangx.Rows[i].Cells["Mahang"].Value.ToString();
slx =
Convert.ToSingle(dgv_hangx.Rows[i].Cells["SLX"].Value.ToString());
dgx =
Convert.ToSingle(dgv_hangx.Rows[i].Cells["DGX"].Value.ToString());
object[] strValue = { stt, SoPX, Mahang, slx, dgx };
dba.ExecuteNonQuery(2, "tbCTPX", strField, strPara,
strValue);
}
for (int j = count - 1; j < dgv_hangx.Rows.Count - 1;
j++)
{
Mahang =
dgv_hangx.Rows[j].Cells["Mahang"].Value.ToString();
stt = SoPX + Mahang;
slx =
Convert.ToSingle(dgv_hangx.Rows[j].Cells["SLX"].Value.ToString());
dgx =
Convert.ToSingle(dgv_hangx.Rows[j].Cells["DGX"].Value.ToString());
object[] strValue = { stt, SoPX, Mahang, slx, dgx };
dba.ExecuteNonQuery(1, "tbCTPX", strField, strPara,
strValue);
}
MessageBox.Show("Lưu chi tiết bán hàng thành công");
}
catch(Exception ex)
{
MessageBox.Show("Lỗi lưu chi tiết bán hàng "+
ex.Message);
}
}
13
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 5: Lập trình sự kiện các điều khiển


1) Sự kiện Load của form frmBanHang
private void frmChiTietBanHang_Load(object sender, EventArgs e)
{
dba = new DBAccess();
index = 0;
CreateGridviewColumn(dgv_hangx);
LoadGridView(dgv_hangx);
LoadComboBoxMaKH();
LoadComboBoxSoPX();
}
2) Sự kiện Click của nút Thêm
private void btThem_Click(object sender, EventArgs e)
{
iu = 0;
SetControl(true);
SetEmpty();
count = 1;
dgv_hangx.Rows.Clear();
}
3) Sự kiện Click của nút Sửa
private void btSua_Click(object sender, EventArgs e)
{
iu = 1;
count = dgv_hangx.RowCount;
SetControl(true);
}
4) Sự kiện Click của nút Lưu
private void btLuu_Click(object sender, EventArgs e)
{
string[] strField = { "SoPX", "NgayX", "Makh" };
string[] strPara = { "@SoPX", "@NgayX", "@Makh" };
object[] strValue = {
cbbSPXuat.Text,dtp_ngayx.Value,cbbMaKH.Text};
try
{
if (iu == 0)
{
//thêm vào một bản ghi bán hàng
dba.ExecuteNonQuery(1, "tbPX", strField, strPara,
strValue);
MessageBox.Show("Một bản ghi phiếu xuất mới được
thêm thành công!");
index = cbbSPXuat.Items.Count;
}
else
{
//cập nhật bản ghi bán hàng
dba.ExecuteNonQuery(2, "tbPX", strField, strPara,
strValue);
MessageBox.Show("Thông tin bản ghi phiếu xuất được
cập nhật thành công!");
index = cbbSPXuat.SelectedIndex;
}
14
Tập bài giảng Lập trình cơ sở dữ liệu

}
catch(Exception ex)
{
MessageBox.Show("Lỗi " + ex.Message);
}
SetControl(false);
btLuuCTPX.Enabled = true;
cbbSPXuat.DropDownStyle = ComboBoxStyle.DropDown;
}
5) Sự kiện Click của nút Xóa
private void btXoa_Click(object sender, EventArgs e)
{
//tạo biến lưu trữ kết quả của người dùng lựa chọn
DialogResult result;
//thông báo cho người dùng trước khi xóa
result = MessageBox.Show("Bạn có chắc chắn xóa bản ghi này
không?", "Cảnh báo!", MessageBoxButtons.YesNo);
string[] strField = { "SoPX" };
string[] strPara = { "@SoPX" };
object[] strValue = { cbbSPXuat.Text };
if (result == DialogResult.Yes)
{
try
{
dba.ExecuteNonQuery(3,"tbCTPX",strField, strPara,
strValue);
dba.ExecuteNonQuery(3, "tbPX", strField, strPara,
strValue);
LoadComboBoxSoPX();
MessageBox.Show("Xóa bản ghi phiếu xuất thành
công");
index = 0;
}
catch(Exception ex)
{
MessageBox.Show("Xóa bản ghi phiếu xuất thất bại!
" + ex.Message);
}
}
}
6) Sự kiện Click của nút Xóa Chi tiết Phiếu xuất
private void btXoaCTPX_Click(object sender, EventArgs e)
{
//lấy vị trí hiện tại
int rowid = dgv_hangx.CurrentRow.Index;
//tạo biến lưu trữ kết quả của người dùng lựa chọn
DialogResult result;
//thông báo cho người dùng trước khi xóa
result = MessageBox.Show("Bạn có chắc chắn xóa bản ghi này
không?", "Cảnh báo!", MessageBoxButtons.YesNo);
string[] strField = { "SoPX", "Mahang" };
string[] strPara = { "@SoPX", "@Mahang" };
object[] strValue = { cbbSPXuat.Text,
dgv_hangx.Rows[rowid].Cells["Mahang"].Value };

15
Tập bài giảng Lập trình cơ sở dữ liệu

if (result == DialogResult.Yes)
{
try
{
dba.ExecuteNonQuery(3, "tbCTPX", strField,
strPara, strValue);
LoadGridView(dgv_hangx);
MessageBox.Show("Xóa chi tiết phiếu xuất thành
công");
}
catch (Exception ex)
{
MessageBox.Show("Xóa bản chi tiết phiếu xuất thất
bại! " + ex.Message);
}
}
}
7) Sự kiện Click của nút Lưu Chi tiết Phiếu xuất
private void btLuuCTPX_Click(object sender, EventArgs e)
{
UpdateDataGridView_Table();
btLuuCTPX.Enabled = false;
LoadComboBoxSoPX();
}
8) Sự kiện RowEnter của DataGridView dgv_hangx
private void dgv_hangx_RowEnter(object sender,
DataGridViewCellEventArgs e)
{
dgv_hangx.Rows[e.RowIndex].Cells[1].Value = cbbSPXuat.Text;
}
9) Sự kiện SelectedIndexChanged của ComBoBox cbbSPXuat
private void cbbSPXuat_SelectedIndexChanged(object sender, EventArgs
e)
{
DataTable dt = dba.GetTable("select * from tbPX where SoPX
= N'" + cbbSPXuat.Text +"'");
if(dt.Rows.Count>0)
{
DataRow px = dt.Rows[0];
cbbMaKH.Text = px["MaKH"].ToString();
dtp_ngayx.Value =
DateTime.Parse(px["NgayX"].ToString());
LoadGridView(dgv_hangx);
}
}
10) Sự kiện SelectedIndexChanged của ComBoBox cbbMaKH
private void cbMaKH_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dt = dba.GetTable("select * from tbKhach where
Makh = N'" + cbbMaKH.Text + "'");
if(dt.Rows.Count>0)
{
DataRow kh = dt.Rows[0];
txtTenKH.Text = kh["Tenkh"].ToString();

16
Tập bài giảng Lập trình cơ sở dữ liệu

}
}

17
Tập bài giảng Lập trình cơ sở dữ liệu

CHƯƠNG 2: LẬP TRÌNH CƠ SỞ DỮ LIỆU SỬ DỤNG LINQ to SQL


2.1. Giới thiệu về LINQ
LINQ (Language Integrated Query) là một thành phần được
giới thiệu trong từ Visual Studio 2008 và .NET Framework 3.5. LINQ giúp khả năng
truy vấn dữ liệu trở nên mạnh mẽ hơn với cú pháp ngôn ngữ C# và Visual Basic. Lập
trình viên trước đây muốn truy vấn đến cơ sở dữ liệu thì việc đầu tiên phải có
chuỗi kết nối; sau đó, lập trình viên phải biết thêm một ngôn ngữ truy vấn cho mỗi loại
cơ sở dữ liệu như: SQL Server, XML, Web Service,…. Commented [A1]: Xuống dòng

Và bây giờ, những việc đó, lập trình viên không cần phải tốn nhiều thời gian để tìm
tòi và học hỏi. LINQ có đầy đủ tính năng mới, cho phép truy vấn dữ liệu trở nên dễ dàng
hơn và có thể áp dụng với nhiều hệ quản trị cơ sở dữ liệu khác nh
au.
2.2. Cú pháp LINQ
Thông thường, lập trình viên làm việc với cơ sở dữ liệu thông qua các truy vấn, phải
học cú pháp truy vấn cho từng loại cơ sở dữ liệu khác nhau như: SQL Server, MySQL,
Oracle, XML. Các hệ quản trị cơ sở dữ liệu về cơ bản có cú pháp giống nhau nhưng vẫn
có nhiều điểm khác nhau để phù hợp với từng hệ quản trị.
LINQ đơn giản hoá các vấn đề trên bằng cách cung cấp cú pháp thích hợp để có thể
làm việc trên tất cả nguồn dữ liệu khác nhau, vì bản chất trong LINQ lập trình viên làm
việc với các đối tượng.
Về mặt cấu trúc, các truy vấn LINQ thường bao gồm ba phần:
- Xác định dữ liệu nguồn
- Tạo truy vấn
- Thực thi truy vấn
Để hiểu rõ hơn xét một ví dụ minh họa sau.
Ví dụ 2.1. Hiển thị các số chẵn trong một mảng các số nguyên.
class Program
{
static void Main(string[] args)
{
//1. Dữ liệu nguồn
int[] numbers = {0, 1, 2, 3, 4, 5, 6};
//2. Tạo truy vấn
var numQuery = from num in numbers
where (num % 2) == 0
select num;
//3. Thực thi truy vấn.
foreach (var num in numQuery)
Console.Write("{0,1} ", num);
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
}
Ví dụ trên sử dụng một mảng số nguyên như dữ liệu nguồn (đối với các nguồn dữ
liệu khác cách thực hiện tương tự). Trong LINQ, thực thi truy vấn tách rời với việc tạo
ra một truy vấn, tức là không thể thu được dữ liệu khi tạo ra một truy vấn. Truy vấn
được tạo ra với mục đích chỉ rõ thông tin nhận từ dữ liệu nguồn, ngoài ra một truy vấn
có thể xác định cách thức sắp xếp, nhóm, hay định dạng dữ liệu trước khi dữ liệu được
trả về. Một truy vấn được lưu trữ trong một biến truy vấn và được khởi tạo bằng một

18
Tập bài giảng Lập trình cơ sở dữ liệu

biểu thức truy vấn. Ba mệnh đề from, where và select được sử dụng trong hầu hết các
truy vấn LINQ. Truy vấn được sử dụng trong ví dụ trên nhằm trả về các số chẵn có trong
mảng số nguyên. Ở đây, ba mệnh đề from, where và select trong biểu thức LINQ có thứ
tự ngược so với thứ tự của chúng trong một truy vấn SQL. Mệnh đề from xác định dữ
liệu nguồn, mệnh đề where để lọc dữ liệu và mệnh đề select xác định loại phần tử được
trả về. Một biến truy vấn (trong ví dụ trên là numQuery) chỉ lưu trữ thông tin được sử
dụng để sinh ra kết quả khi truy vấn được thực thi sau đó.
Trong ví dụ 2.1, truy vấn được thực thi trong vòng lặp foreach và trả về kết quả truy
vấn. Ứng với mỗi lần lặp, biến num sẽ được gán trị là phần tử được trả về từ truy vấn.
Phương thức Console.Write() hiển thị giá trị phần tử được trả về và tiến trình truy vấn
sẽ tiếp tục lặp lại đến khi hết phần tử được trả về từ dữ liệu nguồn.

Hình 2.1. Tiến trình thực thi của truy vấn LINQ.
Để tạo một truy vấn LINQ có 2 cách: sử dụng cú pháp truy vấn (query syntax) hoặc
cú pháp dạng phương thức (method syntax).
a) Cú pháp truy vấn
Cú pháp:
from [range variable] in [data source]
let [expression]
where [boolean expression]
orderby [[expression](ascending/descending)], [optionally repeat]
select [expression]
group [expression] by [expression] into [expression]
Một biểu thức truy vấn được bắt đầu bằng mệnh đề from và có thể kết thúc bằng
mệnh đề select hoặc group by.
- Mệnh đề from được sử dụng nhằm chỉ định dữ liệu nguồn và biến giá trị (range
variable) biểu diễn từng phần tử trong dữ liệu nguồn.
- Mệnh đề where được sử dụng để lọc các phần tử từ dữ liệu nguồn dựa trên các biểu
thức Boolean được kết hợp với nhau bằng các toán tử &&, ||.
- Mệnh đề select được sử dụng để xác định kiểu và định dạng giá trị trả về khi truy
vấn được thực thi.
- Mệnh đề let được sử dụng để tạo ra các biến tạm thời và lưu trữ kết quả của một
biểu thức nào đó trong truy vấn.
19
Tập bài giảng Lập trình cơ sở dữ liệu

Ví dụ 2.2. Sử dụng mệnh đề let để tạo biến tạm thời v có giá trị bằng 100 lần phần tử
trong mảng số nguyên và hiển thị v nếu v > 500.
static void Main(string[] args)
{
int[] array = { 1, 3, 5, 7, 9 };

var result = from element in array


let v = element * 100
where v >= 500
select v;

foreach (var element in result)


Console.WriteLine(element);
Console.ReadKey();
}
Kết quả:
500
700
900
- Mệnh đề group được sử dụng để nhóm kết quả truy vấn theo giá trị khóa.
Ví dụ 2.3. Sử dụng group … by … into để phân chia dãy các từ theo ký tự đầu tiên
của mỗi từ.
static void Main(string[] args)
{
string[] words = { "blueberry", "chimpanzee", "abacus",
"banana", "apple", "cheese" };
var wordGroups =
from w in words
group w by w[0] into g
select new { FirstLetter = g.Key, Words = g };
foreach (var g in wordGroups)
{
Console.WriteLine("Words that start with the letter
'{0}':", g.FirstLetter);
foreach (var w in g.Words)
{
Console.WriteLine(w);
}
}
Console.ReadKey();
}
Kết quả:
Words that start with the letter 'b':
blueberry
banana
Words that start with the letter 'c':
chimpanzee
cheese
Words that start with the letter 'a':
abacus
apple
- Mệnh đề orderby được sử dụng để sắp xếp kết quả truy vấn theo chiều tăng dần
hoặc giảm dần.

20
Tập bài giảng Lập trình cơ sở dữ liệu

b) Cú pháp dạng phương thức


Hầu hết các truy vấn LINQ trong các tài liệu được viết theo dạng cú pháp truy vấn.
Tuy nhiên, khi biên dịch, các truy vấn này cần phải chuyển thành các phương thức mà
CLR có thể hiểu được. Các phương thức này được gọi là các phương thức toán tử truy
vấn chuẩn (Standard Query Operators methods) và có tên giống với các mệnh đề truy
vấn như Where, Select, GroupBy, Join, Max, Average, … Chúng ta có thể sử dụng các
phương thức này để truy vấn thay vì sử dụng cú pháp truy vấn.
Ví dụ 2.4. Sử dụng cú pháp truy vấn và cú pháp dạng phương thức để trả về dãy các
số chẵn của một dãy số nguyên cho trước.
static void Main(string[] args)
{
int[] numbers = { 5, 10, 8, 3, 6, 12 };
//Cú pháp truy vấn LINQ:
var numQuery1 =
from num in numbers
where num % 2 == 0
select num;
//Cú pháp dạng phương thức:
var numQuery2 = numbers.Where(num => num % 2 == 0);
foreach (int i in numQuery1)
{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}
Console.ReadKey();
}
Cú pháp dạng phương thức bao gồm tên phương thức và một biểu thức Lambda được
sử dụng như một tham số của các toán tử phương thức chuẩn.

Hình 2.2. Cấu trúc cú pháp dạng phương thức.


Biểu thức Lambda được dùng để định nghĩa các phương thức giấu tên, có cấu trúc
đơn giản như sau:
(Parameter_Input_Name) => Expression
Cặp dấu () là không bắt buộc với biểu thức chỉ có một tham số. Nếu có từ hai tham
số đầu vào thì các tham số này được phân cách bởi dấu “,” được đặt giữa cặp dấu (). Giá
trị của biểu thức Lambda chính là giá trị của biểu thức phía bên phải toán tử =>. Trong
ví dụ 2.4, biểu thức Lambda có một tham số đầu vào là num, biểu thức là num % 2 ==
0, biểu thức Lambda này có giá trị true nếu num là một số chẵn và là false nếu num là
số lẻ.
21
Tập bài giảng Lập trình cơ sở dữ liệu

Ví dụ 2.5. Hiển thị các số có tên tiếng Anh của nó có độ dài nhỏ hơn giá trị của nó.
static void Main(string[] args)
{
string[] digits = { "zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine" };

var shortDigits = digits.Where((digit, index) =>


digit.Length < index);
Console.WriteLine("Short digits:");
foreach (var d in shortDigits)
{
Console.WriteLine("The word {0} is shorter than its
value.", d);
}
Console.ReadKey();
}
Kết quả:
Short digits:
The word five is shorter than its value.
The word six is shorter than its value.
The word seven is shorter than its value.
The word eight is shorter than its value.
The word nine is shorter than its value.
2.3. Các toán tử truy vấn LINQ
Các toán tử truy vấn chuẩn trong LINQ thực chất là các phương thức mở rộng được
dùng để tạo nên các truy vấn LINQ. Các phương thức này được áp dụng cho các đối
tượng cài đặt giao diện IEnumerable<T> hoặc IQueryable<T>. Các toán tử truy vấn
được phân chia theo chức năng bao gồm lọc, chọn, sắp xếp, hàm gộp, …
1) Phép toán sắp xếp
Phương thức Chức năng Cú pháp truy vấn

OrderBy Sắp xếp theo chiều tăng dần orderby

OrderByDescending Sắp xếp theo chiều giảm dần orderby …


descending

ThenBy Thực hiện tiêu chuẩn sắp xếp thứ hai orderby …, …
theo chiều tăng dần

ThenByDescending Thực hiện tiêu chuẩn sắp xếp thứ hai orderby …, …
theo chiều giảm dần descending
Ví dụ 2.6. Sắp xếp dãy các từ tăng dần theo độ dài, nếu các từ có độ dài bằng nhau
thi sắp xếp theo ký tự đầu tiên của các từ.
static void Main(string[] args)
{
string[] words ={"the","quick","brown","fox","jumps" };
var query = from word in words
orderby word.Length, word.Substring(0, 1)
select word;
//Cách 2:
22
Tập bài giảng Lập trình cơ sở dữ liệu

//var query = words.OrderBy(word => word.Length).ThenBy(word


=> word.Substring(0, 1));
foreach (var str in query)
Console.WriteLine(str);
Console.ReadKey();
}
Kết quả:
fox
the
brown
jumps
quick
2) Phép toán lọc dữ liệu
Phương thức Chức năng Cú pháp truy vấn

Where Lựa chọn giá trị dựa trên một điều where
kiện xác định
3) Phép chọn
Phương thức Chức năng Cú pháp truy vấn

Select Các giá trị được chọn dựa trên các Select
hàm biến đổi

SelectMany Dãy các giá trị được chọn dựa trên Sử dụng nhiều mệnh đề
một hàm biến đổi và sau đó được form
chuyển thành một dãy
Ví dụ 2.7. Sử dụng nhiều mệnh đề from để trả về các từ trong mỗi chuỗi ký tự trong
dãy ký tự.
static void Main(string[] args)
{
List<string> phrases = new List<string>() { "an apple a
day", "the quick brown fox" };

var query = from phrase in phrases


from word in phrase.Split(' ')
select word;
//Cách 2:
//var query = phrases.SelectMany(phrase => phrase.Split('
'));
foreach (string s in query)
Console.WriteLine(s);
Console.ReadKey();
}
4) Phép toán tập hợp
Phương thức Chức năng Cú pháp truy vấn

23
Tập bài giảng Lập trình cơ sở dữ liệu

Distinct Loại bỏ các giá trị trùng nhau trong Không có


tập hợp

Except Trả về tập hiệu của hai tập hợp Không có

Intersect Trả về tập giao của hai tập hợp Không có

Union Trả về hợp của hai tập hợp Không có

Ví dụ 2.8. Trả về tập giao của hai tập số nguyên


static void Main(string[] args)
{
int[] id1 = { 44, 26, 92, 30, 71, 38 };
int[] id2 = { 39, 59, 83, 47, 26, 4, 30 };

IEnumerable<int> both = id1.Intersect(id2);

foreach (int id in both)


Console.WriteLine(id);
Console.ReadLine();
}
Kết quả:
26
30
5) Phép toán lượng hóa
Phương thức Chức năng Cú pháp truy vấn

All Xác định xem tất cả các phần tử Không có


trong dãy có thỏa mãn điều kiện hay
không

Any Xác định xem có phần tử nào trong Không có


dãy thỏa mãn điều kiện hay không

Contains Determines whether a sequence Không có


contains a specified element.
Xác định dãy có chứa một phần từ
nào đó hay không
Ví dụ 2.9. Sử dụng phép toán Any để kiểm tra dãy số có phần tử nào chia hết cho 2,
phần tử nào lớn hơn 3 và phần tử nào bằng 2 hay không.
static void Main()
{
int[] array = { 1, 2, 3 };
// See if any elements are divisible by two.
bool b1 = array.Any(item => item % 2 == 0);
// See if any elements are greater than three.
24
Tập bài giảng Lập trình cơ sở dữ liệu

bool b2 = array.Any(item => item > 3);


// See if any elements are 2.
bool b3 = array.Any(item => item == 2);
// Write results.
Console.WriteLine(b1);
Console.WriteLine(b2);
Console.WriteLine(b3);
}
Kết quả:
True
False
True
6) Phép toán kết nối
Phương thức Chức năng Cú pháp truy vấn

Kết nối hai dãy dựa trên giá trị khóa join … in … on …
Join
khớp nhau equals …

Kếp nối hai dãy và nhóm các phần join … in … on …


GroupJoin
tử khớp nhau lại equals … into …
Ví dụ 2.10. Sử dụng Join để kết hợp hai mảng đối tượng Customer và Order theo
thuộc tính ID bằng nhau của hai lớp.
class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}

class Order
{
public int ID { get; set; }
public string Product { get; set; }
}

class Program
{
static void Main(string[] args)
{
// Example customers.
var customers = new Customer[]
{
new Customer{ID = 5, Name = "Sam"},
new Customer{ID = 6, Name = "Dave"},
new Customer{ID = 7, Name = "Julia"},
new Customer{ID = 8, Name = "Sue"}
};

// Example orders.
var orders = new Order[]
{
new Order{ID = 5, Product = "Book"},
new Order{ID = 6, Product = "Game"},
25
Tập bài giảng Lập trình cơ sở dữ liệu

new Order{ID = 7, Product = "Computer"},


new Order{ID = 8, Product = "Shirt"}
};

// Join on the ID properties.


var query = from c in customers
join o in orders on c.ID equals o.ID
select new { c.Name, o.Product };

// Display joined groups.


foreach (var group in query)
{
Console.WriteLine("{0} bought {1}", group.Name,
group.Product);
}
Console.ReadKey();
}
}
Kết quả:
Sam bought Book
Dave bought Game
Julia bought Computer
Sue bought Shirt
7) Phép toán nhóm
Phương thức Chức năng Cú pháp truy vấn

Nhóm các phần tử theo một thuộc


tính chung. Mỗi nhóm là một đối group … by -or- group
GroupBy
tượng kiểu IGrouping<khóa, phần … by … into …
tử>

Trả về một dãy các phần tử trong đó


ToLookup mỗi phần tử là một nhóm với chỉ Không có
mục là giá trị khóa
Ví dụ 2.11. Sử dụng ToLookup để nhóm các từ trong dãy theo độ dài và liệt kê các
tử trong nhóm theo hai cách
static void Main(string[] args)
{
string[] array = { "cat", "dog", "horse" };
//Nhóm theo độ dài
var lookup = array.ToLookup(item => item.Length);
//Cách 1 liệt kê theo mảng với chỉ mục là độ dài từ
//Liệt kê các chuỗi có độ dài bằng 3
foreach (string item in lookup[3])
{
Console.WriteLine("3 = " + item);
}
//Liệt kê các chuỗi có độ dài bằng 3
foreach (string item in lookup[5])
{
Console.WriteLine("5 = " + item);

26
Tập bài giảng Lập trình cơ sở dữ liệu

}
// Cách 2 liệt kê theo nhóm
foreach (var grouping in lookup)
{
Console.WriteLine("Grouping:");
foreach (string item in grouping)
{
Console.WriteLine(item);
}
}
Console.ReadKey();
}
8) Phép toán chuyển đổi kiểu dữ liệu
Phương thức Chức năng Cú pháp truy vấn

ToArray Chuyển đổi tập các phần tử thành


một mảng. Phương thức đòi hỏi Không có
thực thi truy vấn.

ToDictionary Chuyển đổi các phần tử thành đối Không có


tượng a Dictionary<TKey,
TValue> dựa trên lựa chọn giá trị
khóa. Phương thức đòi hỏi thực thi
truy vấn.

ToList Chuyển đổi tập các phần tử thành Không có


một đối tượng kiểu List<T>.
Phương thức đòi hỏi thực thi truy
vấn.
9) Phép toán ghép nối
Phương thức Chức năng Cú pháp truy vấn

Concat Ghép nối hai chuỗi thành một chuỗi Không có

10) Phép toán gộp


Phương thức Chức năng Cú pháp truy vấn

Aggregate Thực hiện phép toán nào đó với tất Không có


cả các phần tử trong dãy

Average Tính giá trị trung bình của một dãy Không có
số

Count Đếm số phần tử có trong một dãy Không có

27
Tập bài giảng Lập trình cơ sở dữ liệu

LongCount Đếm số phần tử có trong một dãy có Không có


rất nhiều phần tử

Max Xác định giá trị lớn nhất trong một Không có
tập hợp

Min Xác định giá trị nhỏ nhất trong một Không có
tập hợp

Sum Tính tổng các phần tử trong một dãy Không có


số
Ví dụ 2.12. Sử dụng các hàm gộp để thực hiện tính tích, tổng, trung bình dãy số, tìm
phần tử lớn nhất, nhỏ nhất có trong dãy số và đếm số phần tử có trong dãy số.
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int result = array.Aggregate((a, b) => b * a);
// 1 * 2 = 2
// 2 * 3 = 6
// 6 * 4 = 24
// 24 * 5 = 120
Console.WriteLine("Tinh tich cua day so = "+result);
result = array.Sum();
Console.WriteLine("Sum = " + result);
Double resavg = array.Average();
Console.WriteLine("Average = " + resavg);
result = array.Max();
Console.WriteLine("Max = " + result);
result = array.Min();
Console.WriteLine("Min = " + result);
result = array.Count();
Console.WriteLine("Count = " + result);
Console.ReadKey();
}
11) Phép toán phân chia
Phương thức Chức năng Cú pháp truy vấn

Skip Trả về một dãy sau khi bỏ qua một Không có


số phần tử liên tiếp tới một vị trị cụ
thể nào đó trong dãy.

SkipWhile Bỏ qua các phần tử cho đến khi tìm Không có


được phần tử đầu tiên không thỏa
mãn một điều kiện cho trước.

Take Trả về một số phần tử trong dãy và Không có


bỏ qua các phần tử còn lại

28
Tập bài giảng Lập trình cơ sở dữ liệu

TakeWhile Trả về các phần tử cho đến khi tìm Không có


được phần tử đầu tiên không thỏa
mãn điều kiện cho trước.
Ví dụ 2.13. Sử dụng các phép toán phân chia để trả về các dãy số con từ một dãy số
cho trước.
static void Main(string[] args)
{
int[] array = { 1, 3, 5, 7, 9, 11 };
//Bỏ qua ba phần tử đầu tiên
var items1 = array.Skip(3);
Console.WriteLine("Day sau khi bo di ba phan tu");
foreach (var value in items1)
{
Console.WriteLine(value);
}
//Bỏ qua trong khi các phần tử < 6
Console.WriteLine("Day sau khi bo di cac phan tu dau tien <
6");
var items2 = array.SkipWhile(n => n < 6);
foreach (var value in items2)
{
Console.WriteLine(value);
}
//Lấy bốn phần tử đầu tiên
var items3 = array.Take(4);
Console.WriteLine("Bon phan tu dau tien trong day");
foreach (var value in items3)
{
Console.WriteLine(value);
}
Console.WriteLine("Lay cac phan tu dau tien < 10");
//Lấy các phần tử đầu tiên < 10
var items4 = array.TakeWhile(n => n < 10);
foreach (var value in items4)
{
Console.WriteLine(value);
}
Console.ReadKey();
}
12) Phép toán sinh
Phương thức Chức năng Cú pháp truy vấn

DefaultIfEmpty Thay thế một tập rỗng bằng tập một Không có.
phần tử có giá trị mặc định

Empty Trả về một tập rỗng. Không có.

Range Sinh ra một tập chứa một dãy số Không có.

29
Tập bài giảng Lập trình cơ sở dữ liệu

Repeat Sinh ra một tập với các phần tử có Không có.


giá trị bằng nhau.
Ví dụ 2.14. Sử dụng các phép toán sinh để tạo ra một mảng các số nguyên từ 1 đến
5, tạo tập gồm 3 chuỗi ký tự “LINQ”, tạo tập có một phần tử, tạo tập rỗng.
static void Main(string[] args)
{
IEnumerable<int> squares = Enumerable.Range(1, 5).Select(x
=> x * x);

Console.WriteLine("Sinh ra tap voi cac so tu 1 toi 5 va tra


ve binh phuong cua cac so do");

foreach (int num in squares)


{
Console.WriteLine(num);
}

IEnumerable<string> strings =
Enumerable.Repeat("LINQ", 3);
Console.WriteLine("Tao ra mot tap gom 3 phan tu la 3 chuoi
LINQ");
foreach (String str in strings)
{
Console.WriteLine(str);
}

// Tạo một list rỗng.


List<int> list = new List<int>();
var result = list.DefaultIfEmpty();

// Tạo tập có một phần tử với giá trị mặc định của kiểu số
nguyên là 0.
Console.WriteLine("Tao tap co 1 phan tu voi gia tri la gia
tri mac dinh kieu so nguyen bang 0");
foreach (var value in result)
{
Console.WriteLine(value);
}
Console.WriteLine("Tao tap co 1 phan tu voi gia tri la -1");
result = list.DefaultIfEmpty(-1);

// Tạo tập có một phần tử với giá trị bằng -1


foreach (var value in result)
{
Console.WriteLine(value);
}
// Tạo tập rỗng
Console.WriteLine("Tao tap rong");
var empty = Enumerable.Empty<int>();
Console.Write("So phan tu tap hop = ");
Console.WriteLine(empty.Count());
Console.ReadLine();
}
30
Tập bài giảng Lập trình cơ sở dữ liệu

13) Phép toán nhóm


Phương thức Chức năng Cú pháp truy vấn

ElementAt Trả về phần tử theo chỉ mục trong Không có.


môt tập hợp

ElementAtOrDefault Trả về phần tử theo chỉ mục trong Không có.


môt tập hợp hoặc giá trị mặc định
nếu chỉ mục nằm ngoài phạm vi cho
phép của tập hợp

First Trả về phần tử đầu tiên của tập hợp Không có.
hoặc phần tử đầu tiên thỏa mãn một
điều kiện cho trước

FirstOrDefault Trả về phần tử đầu tiên của tập hợp Không có.
hoặc phần tử đầu tiên thỏa mãn một
điều kiện cho trước. Trả về giá trị
mặc định nếu phần tử đó không tồn
tại.

Last Trả về phần tử cuối cùng của tập Không có.


hợp hoặc phần tử cuối cùng thỏa
mãn một điều kiện cho trước.

LastOrDefault Trả về phần tử cuối cùng của tập Không có.


hợp hoặc phần tử cuối cùng thỏa
mãn một điều kiện cho trước. Trả về
giá trị mặc định nếu phần tử đó
không tồn tại.

Single Trả về phần tử duy nhất của tập hợp Không có.
hoặc phần tử duy nhất thỏa mãn một
điều kiện cho trước.

SingleOrDefault Trả về phần tử duy nhất của tập hợp Không có.
hoặc phần tử duy nhất thỏa mãn một
điều kiện cho trước. Trả về giá trị
mặc định nếu phần tử đó không tồn
tại hoặc tập hợp không chứa phần tử
đó.
Ví dụ 2.15. Sử dụng SingleOrDefault để xác định xem trong dãy số nguyên có tồn tại
duy nhất một phần tử thỏa mã điều kiện cho trước hay không
static void Main(string[] args)
{
int[] array = { 1, 2, 3 };

31
Tập bài giảng Lập trình cơ sở dữ liệu

// Trả về giá trị mặc định nếu không tìm thấy phần tử nào
bằng 5
int a = array.SingleOrDefault(element => element == 5);
Console.WriteLine(a);
// Trả về phần tử 1 duy nhất.
int b = array.SingleOrDefault(element => element == 1);
Console.WriteLine(b);
try
{
// Ngoại lệ được sinh ra nếu có từ 2 phần tử được tìm
thấy.
int c = array.SingleOrDefault(element => element >= 1);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType());
}
Console.ReadKey();
}
2.4. Mô hình LINQ to SQL
2.4.1. Khái niệm
LINQ to SQL là một thành phần của .NET Framework 3.5, cung cấp một cơ sở hạ
tầng cho việc quản lý các dữ liệu quan hệ như các đối tượng. Trong LINQ to SQL, mô
hình dữ liệu của cơ sở dữ liệu quan hệ được ánh xạ sang mô hình đối tượng được biểu
diễn trong ngôn ngữ lập trình C# hay Visual Basic. Khi ứng dụng được thực thi, LINQ
to SQL sẽ chuyển các truy vấn LINQ trong mô hình đối tượng thành truy vấn SQL và
gửi tới cơ sở dữ liệu để thực hiện. Sau đó kết quả trả về từ cơ sở dữ liệu sẽ được LINQ
to SQL chuyển ngược lại thành đối tượng trong ứng dụng.
2.4.2. Các lớp thực thể và DataContext
Bằng cách ánh xạ một bảng trong cơ sở dữ liệu thành một lớp, ta có thể thao tác dữ
liệu trên đó bằng mã lệnh lập trình và bao gồm cả LINQ. Các lớp được ánh xạ này được
gọi là các lớp thực thể. Như vậy, một lớp được sẽ được ánh xạ đến một bảng, theo đó
một thuộc tính sẽ được dùng để ánh xạ cho một cột của bảng.Việc ánh xạ này được gọi
là ORM (object-relational mapping), đây là đặc điểm cơ bản của LINQ to SQL.
Việc ánh xạ này trong .NET được áp dụng bằng cách thiết lập các attribute cho lớp,
thuộc tính, phương thức, … kĩ thuật này được gọi là Attribute-based Mapping. Bảng sau Commented [A2]: khoảng cách

đây cho thấy các ánh xạ tương ứng của các đối tượng database vào các đối tượng lập
trình:
Mô hình đối tượng LINQ to SQL Mô hình dữ liệu quan hệ

DataContext Cơ sở dữ liệu

Lớp thực thể (Entity class) Bảng

Thuộc tính lớp (Class member) Cột trong bảng

Mối liên hệ (Association) Quan hệ khóa ngoại

32
Tập bài giảng Lập trình cơ sở dữ liệu

Phương thức (Method) Thủ tục hoặc hàm


Trong LINQ to SQL, các bảng dữ liệu được thể hiện bằng các lớp thực thể. Một lớp
thực thể khác với lớp thông thường ở chỗ cần chỉ rõ thông tin liên kết giữa lớp thực thể
và bảng dữ liệu bằng cách gán thuộc tính TableAttribute trong phần định nghĩa lớp như
trong ví dụ sau.
Ví dụ 2.16. Định nghĩa lớp Customerzz và liên kết với bảng Customers
[Table(Name = "Customers")]
public class Customerzz
{
public string CustomerID;
// ...
public string City;
}
Tương tự như vậy cần thiết lập mối quan hệ giữa các thuộc tính lớp với cột trong
bảng dữ liệu và mối liên kết LINQ to SQL với quan hệ khóa ngoại.
DataContext
DataContext là một đối tượng đại diện cho toàn bộ cơ sở dữ liệu tương tự như
DataSet, nhưng được kết hợp chức năng của các đối tượng connection, command và
data adapter trong ADO.NET. DataContext được tạo ra trong quá trình xây dựng mô
hình đối tượng LINQ và các lớp thực thể sẽ được truy cập thông qua DataContext.
2.4.3. Thiết kế mô hình LINQ to SQL
Để thiết kế mô hình LINQ to SQL
Bước 1: Tạo một dự án Windows Forms Application mới và đặt tên là
QLKD_LINQ2SQL.

Hình 2.3. Tạo dự án QLKD_LINQ2SQL.


Bước 2: Tạo mới mô hình LINQ to SQL.
- Kích chuột phải dự án QLKD_LINQ2SQL/Chọn Add/Chọn New Item.
- Chọn LINQ to SQL Classes/Nhập tên QLKD tại mục Name/Chọn Add. Cửa sổ
Object Relational Designer sẽ xuất hiện như hình Hình 2.5.

33
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 2.4. Tạo mới mô hình LINQ to SQL .

Hình 2.5. Object Relational Designer.


Bước 3: Kết nối cơ sở dữ liệu QLKD với dự án QLKD_LINQ2SQL .
- Trong cửa sổ Object Relational Designer, kích chọn vào liên kết Server Explorer để
mở cửa sổ Server Explorer.
- Trong cửa sổ Server Explorer, kích chuột phải chọn mục Data Connections và chọn
Add Connection để mở hộp thoại Add Connection.
- Trong hộp thoại Add Connection thiết lập kết nối tới cơ sở dữ liệu nguồn:
+ Nhập tên Server tại mục Server Name
+ Chọn chế độ đăng nhập tại mục Log on to the Server:
Trường hợp 1: Đăng nhập bằng tài khoản Window thì chọn Use Window
Authentication
+ Trường hợp 2: Đăng nhập bằng tài khoản SQL Server thì chọn Use SQL Server
Authentication/Nhập tên User Name/Nhập Passwork
+ Chọn cơ sở dữ liệu tại mục Select or Enter Database Name và chọn OK

34
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 2.6. Chọn cơ sở dữ liệu nguồn

Hình 2.7. Cửa sổ Server Explorer sau khi kết nối với cơ sở dữ liệu QLKD.
Bước 4: Tạo các lớp thực thể tương ứng với các bảng thuộc cơ sở dữ liệu QLKD.
Lần lượt kéo các bảng từ cửa sổ Server Explorer vào Object Relational Designer ta
sẽ được mô hình LINQ to SQL của cơ sở dữ liệu QLKD.

35
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 2.8. Lược đồ cơ sở dữ liệu QLKD.

Hình 2.9. Mô hình đối tượng QLKD.


Chú ý: Sau khi tạo mới mô hình LINQ to SQL, thư mục QLKD.dbml được thêm vào
dự án và xuất hiện trong cửa sổ Solution Explorer như Hình 2.5. Trong thư mục này có
hai tập tin: QLKD.dbml.layout và QLKD.designer.cs. Tập tin QLKD.dbml.layout mô
tả cơ sở dữ liệu được sử dụng để sinh ra các lớp thực thể. Tập tin QLKD.designer.cs
được sinh ra tự động bởi Object Relational Designer, chứa mã lệnh để tạo ra lớp con
QLKDDataContext được thừa kế từ lớp DataContext và các lớp thực thể tương ứng với
các bảng trong cơ sở dữ liệu QLKD.

36
Tập bài giảng Lập trình cơ sở dữ liệu

2.5. Truy vấn cơ sở dữ liệu sử dụng LINQ to SQL


2.5.1. Đối tượng DataContext
Để xử lý dữ liệu trong ứng dụng sử dụng LINQ to SQL việc khai báo đối tượng
DataConext của mô hình đối tượng là cần thiết.
Cú pháp:
[<Access_Range>] <DataContext_Class> <DataContext_Name> = new
<DataContext_Class>();
Trong đó:
- DataContext_Class: Lớp con thừa kế từ lớp DataContext được sinh ra từ mô hình
dữ liệu.
- DataContext_Name: Tên của đối tượng DataContext_Class
- Access_Range: Phạm vi truy cập của đối tượng (public, private, …)
Ví dụ:
QLKDDataContext qlkd = new QLKDDataContext();
1) Các hàm tạo lớp DataContext
Hàm tạo Mô tả

DataContext(IDbConnection) Khởi tạo đối tượng lớp DataContext theo


đối tượng IDBConnection

DataContext(IDbConnection, Khởi tạo đối tượng lớp DataContext theo


MappingSource) đối tượng IDBConnection và nguồn
thông tin ánh xạ

DataContext(String) Khởi tạo đối tượng lớp DataContext theo


tập tin nguồn hoặc chuỗi kết nối

DataContext(String, Khởi tạo đối tượng lớp DataContext theo


MappingSource) tập tin nguồn hoặc chuỗi kết nối và nguồn
thông tin ánh xạ
2) Các thuộc tính
Thuộc tính Mô tả

Connection Trả về kết nối được sử dụng

Transaction Trả về hoặc thiết lập phiên làm việc để


truy nhập cơ sở dữ liệu
3) Các phương thức
Phương thức Mô tả

CreateDatabase() Tạo một cơ sở dữ liệu trên máy chủ

DatabaseExists() Xác định cơ sở dữ liệu có được mở hay


không

37
Tập bài giảng Lập trình cơ sở dữ liệu

DeleteDatabase() Xoá cơ sở dữ liệu

SubmitChanges() Cập nhật các thay đổi trên cơ sở dữ liệu

ExecuteQuery(Of TResult)(String, Thực thi truy vân SQL trên cơ sở dữ liệu


Object()) và giá trị trả về là các đối tượng
2.5.2. Khai báo thực thể Commented [A3]: Lớp

Cú pháp:
[<Access_Range>] <Entity_Class_Name> <Entity_Name>= new
<Entity_Class_Name>();
Trong đó:
- Entity_Name: Tên đối tượng thực thể
- Entity_Class_Name: Tên lớp tập thực thể
Ví dụ:
public tbHang newmh = new tbHang();
2.5.3. Lấy thuộc tính của thực thể Commented [A4]: lớp

Cú pháp:
<Entity_Name>.<Property_Name>
Trong đó: Property_Name: Tên của thuộc tính của thực thể
Ví dụ:
newmh.Mahang = txtMaMH.Text;
2.6. Làm việc với cơ sở dữ liệu sử dụng LINQ to SQL
2.6.1. Thêm dữ liệu
Để thêm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc
sử dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL thực hiện các
bước sau:
Bước 1: Khai báo đối tượng lớp DataContext DataContext_Class
<DataContext_Class> <DataContext_Name> = new <DataContext_Class>();
Bước 2: Khai báo một thực thể
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
Bước 3: Gán giá trị cho các thuộc tính của thực thể
<Entity_Name>.<Property_Name1>=<Value1>

<Entity_Name>.<Property_Namen>=<Valuen>
Bước 4: Gọi phương thức thêm một thực thể vào tập thực thể
<DataContext_Name>.<Entity_Class_Name>s.
InsertOnSubmit<TEntity>(< Entity_Name>)
Bước 5: Lưu lại các thay đổi của tập thực thể vào cơ sở dữ liệu
<DataContext_Name>.SubmitChanges()
Chú ý
Ví dụ:
//Bước 1
QLKDDataContext qlkdDC = new QLKDDataContext();
//Bước 2
tbHang newtbHang = new tbHang();
//Bước 3
newtbHang.Mahang = txtMaMH.Text;

38
Tập bài giảng Lập trình cơ sở dữ liệu

newtbHang.Tenhang = txtTenMH.Text;
newtbHang.Dvt = txtDVT.Text;
//Bước 4
qlkdDC.tbHangs.InsertOnSubmit(newtbHang);
//Bước 5
qlkdDC.SubmitChanges();
2.6.2. Xóa dữ liệu
Để xóa một bản ghi trong bảng cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL thực hiện các
bước sau:
Bước 1: Khai báo đối tượng lớp DataContext_Class
<DataContext_Class> <DataContext_Name> = new <DataContext_Class>();
Bước 2: Lấy ra thực thể cần xóa
- Khai báo thực thể lớp cần xóa
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
- Tìm đối tượng cần xóa và gán cho đối tượng thực thể
Cách 1: Sử dụng cú pháp dạng phương thức
var <query>
=<DataContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression);
Cách 2:Sử dụng cú pháp truy vấn
var <query> = from <element> in <DataContext_Name>.<Entity_Class_Name>s
where <Search_Expresion> select <element>;
- Gán đối tượng đầu tiên tìm thấy cho thực thể cần xóa
<Entity_Name> = <query>.SingleOrDefault();
Bước 3: Gọi phương thức xóa thực thể trong tập thực thể
<DataContext_Name>.<Entity_Class_Name>s.DeleteOnSubmit (<Entity_Name>);
Bước 4: Lưu lại các thay đổi của tập thực thể vào cơ sở dữ liệu
<DataContext_Name>.SubmitChanges();
Ví dụ: Xóa bản ghi có mã mặt hàng “MMH01”
QLKDDataContext qlkdDC = new QLKDDataContext();
tbHang hang = new tbHang();
var query = qlkdDC.tbHangs.Where<tbHang>(n => n.Mahang == "MMH01");
hang = query.SingleOrDefault();
qlkdDC.tbHangs.DeleteOnSubmit(hang);
qlkdDC.SubmitChanges();
2.6.3. Tìm kiếm thông tin
Để tìm kiếm thông tin trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ cơ sở dữ liệu trong mô hình LINQ to SQL gồm các
trường hợp và các bước sau:
1) Tìm kiếm không điều kiện
- Đưa dữ liệu lên Combobox
<ComboBox_Name>.DataSource = <DataContext_Name>.<Entity_Class_Name>s;
<ComboBox_Name>.DisplayMember = "<FieldName>";
<ComboBox_Name>.ValueMember = "<FieldName>";
Ví dụ:
cbMahang.DataSource = qlkdDC.tbHangs;
cbMahang.DisplayMember = "Tenhang";
cbMahang.ValueMember = "Mahang";
- Đưa dữ liệu lên DataGridView:
<DataGridView_Name>.DataSource=<DataContext_Name>.<Entity_Class_Name>s;
Ví dụ:
39
Tập bài giảng Lập trình cơ sở dữ liệu

dg_Hienthi.DataSource = qlkdDC.tbHangs;
2) Tìm kiếm có điều kiện
- Tìm đối tượng và gán cho đối tượng thực thể
Cách 1: Sử dụng cú pháp dạng phương thức
var
<query>=<DataContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression)
Cách 2:Sử dụng cú pháp truy vấn
var <query> = from <element> in
<DataContext_Name>.<Entity_Class_Name>s where <Search_Expresion> select
<element>;
- Hiển thị dữ liệu lên các đối tượng trên Form
+ Trên Combox:
<ComboBox_Name>.DataSource = <query>;
<ComboBox_Name>.DisplayMember = "<FieldName>";
<ComboBox_Name>.ValueMember = "<FieldName>";
+ Trên DataGridView:
<DataGridView_Name>.DataSource=<query>;
+ Trên TextBox:
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
<Entity_Name> = <query>.SingleOrDefault();
<TextBox_Name>.Text = <Entity_Name>.<Property_Name>;
Ví dụ: Hiển thị dữ liệu lên đối tượng Combobox và Datagridview
//Sử dụng cú pháp truy vấn
var query = from n in qlkdDC.tbHangs
where n.Tenhang.Contains(txtTenMH.Text)
select n;
cbbMatHang.DataSource = query;
cbbMatHang.DisplayMember = “TenHang”;
cbbMatHang.ValueMember = “MaHang”;
//Sử dụng cú pháp dạng phương thức
query = qlkdDC.tbHangs.Where(n=> n.Tenhang.Contains(txtTenMH.Text));
dg_Hienthi.DataSource = query;
//Hiển thị dữ liệu trên TextBox
var query = from n in qlkdDC.tbHangs
where n.Mahang == "MMH01"
select n;
tbHang hang = new tbHang();
hang = query.SingleOrDefault();
if (hang != null) txtTenMH.Text = hang.Tenhang;
2.6.4. Sửa dữ liệu
Để sửa một bản ghi trong bảng cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL thực hiện các
bước sau:
Bước 1: Khai báo đối tượng lớp DataContext DataContext_Class
<DataContext_Class> <DataContext_Name> = new <DataContext_Class>();
Bước 2: Lấy ra thực thể cần sửa
- Khai báo thực thể lớp cần sửa
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
- Tìm đối tượng cần sửa và gán cho đối tượng thực thể
Cách 1: Sử dụng cú pháp dạng phương thức
var <query>
=<DataContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression;
40
Tập bài giảng Lập trình cơ sở dữ liệu

Cách 2:Sử dụng cú pháp truy vấn


var <query> = from <element> in
<DataContext_Name>.<Entity_Class_Name>s where <Search_Expresion> select
<element>;
- Gán đối tượng đầu tiên tìm thấy cho thực thể cần xóa
<Entity_Name> = <query>.SingleOrDefault();
Bước 3: Gán giá trị cho các thuộc tính của thực thể
<Entity_Name>.<Property_Name1>=<Value1>

<Entity_Name>.<Property_Namen>=<Valuen>
Bước 4: Lưu lại các thay đổi của tập thực thể vào cơ sở dữ liệu
<DataContext_Name>.SubmitChanges();
Ví dụ: Cập nhật một bản ghi bảng tbHang
QLKDDataContext qlkdDC = new QLKDDataContext();
tbHang hang = new tbHang();
var query = qlkdDC.tbHangs.Where<tbHang>(n => n.Mahang == "MMH01");
hang = query.SingleOrDefault();
hang.Dvt = txtDVT.Text;
hang.Tenhang = txtTenMH.Text;
qlkdDC.SubmitChanges();
2.6.5. Các ví dụ
Ví dụ 2.17. Form quản lý các nhà cung cấp có mẫu sau. Hãy sử dụng mô hình LINQ
to SQL để thực hiện việc thêm, sửa, xóa thông tin của nhà cung cấp các mặt hàng.

Hình 2.10. Giao diện Form quản lý nhà cung cấp.


Bước 1: Tạo và thiết kế Form Quản lý các nhà cung cấp mặt hàng

41
Tập bài giảng Lập trình cơ sở dữ liệu

STT Đối tượng Thuộc tính Giá trị


Name frm_NCC
1 Form
Text Quản lý các nhà cung cấp
2 Label Text Mã nhà cung cấp
3 Label Text Tên nhà cung cấp
4 Label Text Địa chỉ nhà cung cấp
5 GroupBox Text Thông tin nhà cung cấp
6 GroupBox Text Danh sách nhà cung cấp
7 GroupBox Text Quản lý nhà cung cấp
8 TextBox Name txtMaNCC
9 TextBox Name txtTenNCC
10 TextBox Name txtDCNCC
Name btnThem
11 Button
Text Nhập mới
Name btnHieuchinh
12 Button
Text Hiệu chỉnh
Name btnLuu
13 Button
Text Lưu
14 DataGridView Name dg_HienThi
Name btXoa
15 Button
Text Xóa
Name btTimKiem
16 Button
Text Tìm Kiếm
Bước 2: Khai báo các tham số
QLKDDataContext qlkdDC;
int iu;
tbNCC currentHang;
Bước 3: Lập trình các phương thức:
1) Phương thức hiện thị trên lưới
void Show_GridView()
{
var query = from n in qlkdDC.tbNCCs select n;
dg_Hienthi.DataSource = query.ToList();
}
2) Phương thức làm trắng các TextBox
private void Set_Empty()
{
txtDCNCC.Text = "";
txtMaNCC.Text = "";
txtTenNCC.Text = "";
}
3) Phương thức trả về thực thể tbNCC theo mã nhà cung cấp
private tbNCC Get_Current(string mancc)
{
tbNCC temp = new tbNCC();
temp = qlkdDC.tbNCCs.Where<tbNCC>(n => n.Mancc ==
mancc).SingleOrDefault();
return temp;
}

42
Tập bài giảng Lập trình cơ sở dữ liệu

4) Phương thức trả về thực thể tbNCC mới


private tbNCC Get_New()
{
tbNCC newtbNCC = new tbNCC();
newtbNCC.Mancc = txtMaNCC.Text;
newtbNCC.Tenncc = txtTenNCC.Text;
newtbNCC.Diachi = txtDCNCC.Text;
return newtbNCC;
}
Bước 4: Lập trình sự kiện frm_NCC_Load của form frm_NCC
private void frm_NCC_Load(object sender, EventArgs e)
{
qlkdDC = new QLKDDataContext();
currentHang = new tbNCC();
dg_Hienthi.SelectionMode =
DataGridViewSelectionMode.FullRowSelect;
Show_GridView();
}
Bước 5: Lập trình sự kiện các nút
1) Sự kiện Click nút btnThem
private void btnThem_Click(object sender, EventArgs e)
{
iu = 0;
Set_Empty();
btnLuu.Enabled = true;
btnThem.Enabled = false;
}
2) Sự kiện Click nút btnHieuchinh
private void btnHieuchinh_Click(object sender, EventArgs e)
{
iu = 1;
btnLuu.Enabled = true;
btnHieuchinh.Enabled = false;
txtMaNCC.Enabled = false;
}
3) Sự kiện Click nút btnLuu
private void btnLuu_Click(object sender, EventArgs e)
{
if (txtMaNCC.Text != "" && txtTenNCC.Text != "" &&
txtDCNCC.Text != "")
{
if (iu == 0)
{
currentHang = Get_Current(txtMaNCC.Text);
//Kiểm tra xem tồn tại trùng mã chưa
if (currentHang == null)
{
tbNCC newtbNCC = Get_New();
qlkdDC.tbNCCs.InsertOnSubmit(newtbNCC);
qlkdDC.SubmitChanges();
MessageBox.Show("Thêm mới thành công", "Thông
báo");
}

43
Tập bài giảng Lập trình cơ sở dữ liệu

else MessageBox.Show("Trùng mã nhà cung cấp", "Thông


báo");
}
else
{
currentHang = Get_Current(txtMaNCC.Text);
currentHang.Diachi = txtDCNCC.Text;
currentHang.Tenncc = txtTenNCC.Text;
qlkdDC.SubmitChanges();
MessageBox.Show("Cập nhật thành công", "Thông báo");
}
btnLuu.Enabled = false;
btnThem.Enabled = true;
btnHieuchinh.Enabled = true;
txtMaNCC.Enabled = true;
Show_GridView();
}
else
{
MessageBox.Show("Dữ liệu nhập chưa hợp lệ", "Thông
báo");
}
}
4) Sự kiện Click nút btXoa
private void btnXoa_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
tbNCC curentNCC = new tbNCC();
var query = qlkdDC.tbNCCs.Where<tbNCC>(n => n.Mancc ==
txtMaNCC.Text);
curentNCC = query.SingleOrDefault();
if (currentHang != null)
{
qlkdDC.tbNCCs.DeleteOnSubmit(curentNCC);
qlkdDC.SubmitChanges();
MessageBox.Show("Xóa thành công", "Thông báo");
Show_GridView();
}
}
}
Bước 6: Lập trình sự kiện SelectionChanged của DataGridView dg_Hienthi
private void dg_Hienthi_SelectionChanged(object sender, EventArgs e)
{
if (dg_Hienthi.SelectedRows.Count > 0)
{
txtMaNCC.Text = dg_Hienthi.CurrentRow.Cells[0].Value.ToString();
txtTenNCC.Text = dg_Hienthi.CurrentRow.Cells[1].Value.ToString();
txtDCNCC.Text = dg_Hienthi.CurrentRow.Cells[2].Value.ToString();
}
}
Ví dụ 3.1. Form quản lý phiếu xuất hàng có mẫu sau. Sử dụng mô hình LINQ to SQL
để thực hiện việc xuất hàng.
44
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 2.11. Giao diện Form quản lý phiếu xuất hàng.


Bước 1: Tạo và thiết kế Form Quản lý phiếu nhập hàng
STT Đối tượng Thuộc tính Giá trị
Name frmXuatHang
1 Form
Text Quản lý phiếu xuất hàng
2 Label Text Mã nhà khách hàng
3 Label Text Tên khách hàng
4 Label Text Địa chỉ khách hàng
5 Label Text Số phiếu
6 Label Text Ngày xuất
7 Label Text Tổng tiền:
8 Label Text Số lượng
Text Thông tin phiếu xuất hàng
9 GroupBox Enabled False
Name gbThongTinPhieuXuatHang
Text Danh sách hàng xuất
10 GroupBox Enabled False
Name gbDanhSachHangXuat
Text Thông tin khách hàng
11 GroupBox Enabled False
Name gbThongTinKhachHang
Text Danh sách mặt hàng
12 GroupBox Enabled False
Name gbDanhSachMatHang
13 ComboBox Name cbMaKH
Name ttxtTenKH
14 TextBox
Enabled False
Name txtDCKH
15 TextBox
Enabled False
16 TextBox Name txtSPXuat
17 TextBox Name txtSL
45
Tập bài giảng Lập trình cơ sở dữ liệu

STT Đối tượng Thuộc tính Giá trị


Enabled False
Name txtTongTien
18 TextBox
Enabled False
19 DateTimePicker Name dtp_ngayx
20 DataGridView Name dgv_hangx
Name btnThem
21 Button
Text Thêm>>
Button Name btnGiam
22
Text <<Giảm
Button Name btnThemMoi
23
Text Nhập mới
Name btnLuu
24 Button
Text Luu
25 DataGridView Name dgv_mathang
Bước 2: Khai báo các đối tượng
QLKDEntities qlkdDB = new QLKDEntities();
List<string> mhlist = new List<string>();
Bước 3: Lập trình các phương thức:
1) Phương thức thêm mã hàng và tên hàng vào lưới mặt hàng xuất
void PopulateDataGridView(string ma, string ten, int soluong,
double dongia)
{
double tt = soluong * dongia;
dgv_hangx.Rows.Add(ma, ten, soluong, dongia, tt);
}
3) Phương thức thêm một thực thể vào tập thực thể tbCTPX với dữ liệu là hàng thứ i
trong DataGridView dgv_hangx
void Insert_CTPX(int i)
{
tbCTPX newctpx = new tbCTPX();
newctpx.SoPX = txtSPXuat.Text;
newctpx.SoTT = txtSPXuat.Text +
dgv_hangx.Rows[i].Cells[0].Value;
newctpx.Mahang =
dgv_hangx.Rows[i].Cells[0].Value.ToString();
newctpx.SLX =
int.Parse(dgv_hangx.Rows[i].Cells[2].Value.ToString());
newctpx.DGX =
int.Parse(dgv_hangx.Rows[i].Cells[3].Value.ToString());
qlkdDC.tbCTPXes.InsertOnSubmit(newctpx);
}
4) Phương thức thêm một thực thể vào tập thực thể tbPX
void Insert_PX()
{
tbPX newpx = new tbPX();
newpx.SoPX = txtSPXuat.Text;
newpx.Makh = cbMaKH.Text;
newpx.NgayX = Convert.ToDateTime(dtp_ngayx.Text);
qlkdDC.tbPXes.InsertOnSubmit(newpx);
}
46
Tập bài giảng Lập trình cơ sở dữ liệu

5) Phương thức vô hiệu hóa một số điều khiển


void Set_Enable(bool value)
{
dgv_hangx.Rows.Clear();
btnLuu.Enabled = value;
btnThemMoi.Enabled = !value;
gbThongTinKhachHang.Enabled = value;
gbThongTinPhieuXuatHang.Enabled = value;
gbDanhSachHangXuat.Enabled = value;
gbDanhSachMatHang.Enabled = value;
txtSL.Enabled = value;
btnGiam.Enabled = value;
btnThem.Enabled = value;
txtSPXuat.Text = "";
txtSL.Text = "1";
}
6) Phương thức tính tổng tiền
private double CaculateSum()
{
double sum = 0;
foreach (DataGridViewRow row in dgv_hangx.Rows)
{
double tt = double.Parse(row.Cells[4].Value.ToString());
sum += tt;
}
return sum;
}
7) Phương thức thêm hoặc xóa một mặt hàng muốn mua
private void YourCart(bool status)
{
if (status)
{
string mamh =
dgv_mathang.CurrentRow.Cells[0].Value.ToString();
var slnQuery = from pn in qlkdDC.tbCTPNs
where (pn.SLN > 0 && pn.Mahang == mamh)
select pn;
tbCTPN p = slnQuery.First();
int index = mhList.IndexOf(mamh);
if (index < 0)
{
int sl = int.Parse(txtSL.Text);
if (p.SLN < sl)
{
MessageBox.Show("Số lượng mua quá số lượng cho
phép", "Thông báo");
return;
}
double dg = double.Parse(
dgv_mathang.CurrentRow.Cells[4].Value.ToString());
PopulateDataGridView(dgv_mathang.CurrentRow.Cells[0].Value.ToString(),
dgv_mathang.CurrentRow.Cells[1].Value.ToString(), sl, dg);
mhList.Add(mamh);
}

47
Tập bài giảng Lập trình cơ sở dữ liệu

}
else
{
string mamh =
dgv_hangx.CurrentRow.Cells[0].Value.ToString();
int index = mhList.IndexOf(mamh);
if (index >= 0)
{
mhList.RemoveAt(index);
dgv_hangx.Rows.RemoveAt(index);
}
}
txtTongTien.Text = CaculateSum().ToString();
}
8) Phương thức hiển thị dữ liệu lưới mặt hàng
private void Load_GridView_Mathang()
{
var hangQuery = from h in qlkdDC.tbHangs
join pn in qlkdDC.tbCTPNs on h.Mahang equals
pn.Mahang
where pn.SLN > 0
select new { h.Mahang, h.Tenhang, h.Dvt,
pn.SLN, DG = pn.DGN * 2 };
dgv_mathang.DataSource = hangQuery.ToList();
}
Bước 6: Lập trình sự kiện Click của nút Nhập mới
private void btnThem_Click(object sender, EventArgs e)
{
Set_Enable(true);
}
Bước 7: Lập trình cho sự kiện Click của nút Lưu
private void btnLuu_Click(object sender, EventArgs e)
{
Set_Enable(false);
dgv_hangx.Rows.Clear();
if (txtSPXuat.Text != "" && cbMaKH.Text != "")
{
//Lưu vào bảng phiếu xuất
Insert_PX();
//Lưu vào bảng chi tiết phiếu xuất
for (int i = 0; i <= dgv_hangx.Rows.Count - 2; i++)
Insert_CTPX(i);
qlkdDC.SubmitChanges();
MessageBox.Show("Đã lưu vào cơ sở dữ liệu", "Thông
báo");
}
}
Bước 8: Lập trình sự kiện SelectedIndexChanged của Combox
private void cbMaKH_SelectedIndexChanged(object sender, EventArgs e)
{
var khQuery = from kh in qlkdDC.tbKhaches where kh.Makh ==
cbMaKH.Text select kh;
tbKhach khach = khQuery.FirstOrDefault();
if (khach != null)

48
Tập bài giảng Lập trình cơ sở dữ liệu

{
txtTenKH.Text = khach.Tenkh;
txtDCKH.Text = khach.Diachi;
}
}
Bước 9: Lập trình sự kiện Click của nút <<Giảm
private void btnGiam_Click(object sender, EventArgs e)
{
YourCart(false);
}
Bước 10: Sự kiện Load của form frmXuatHang
private void frmXuatHang_Load(object sender, EventArgs e)
{
Load_GridView_Mathang();
cbMaKH.DataSource = qlkdDC.tbKhaches.ToList();
cbMaKH.DisplayMember = "makh";
}
Bước 11: Lập trình sự kiện Click của nút Thêm>>
private void btnThem_Click(object sender, EventArgs e)
{
YourCart(true);
}

2.7. Sử dụng LINQ to SQL kết hợp với Stored Procedure


2.7.1. Đưa Stored Procedure vào mô hình LINQ to SQL
Để thêm Stored Procedure vào mô hình, chọn và kéo thủ tục từ cửa sổ Server
Explorer vào mô hình LINQ to SQL.

Hình 2.12. Thêm thủ tục TraveNCC vào mô hình LINQ to SQL.
2.7.2. Thêm dữ liệu
Để thêm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc
sử dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL kết hợp với
Stored Procedure gồm các bước sau:
Bước 1: Tạo thủ tục thêm trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,

49
Tập bài giảng Lập trình cơ sở dữ liệu

….
@VField_Namen <Date_Typen>
AS
BEGIN
INSERT INTO <Table_name>(Field_Name1,.., Field_Namen)
VALUES(@VField_Name1,..,@VField_Namen)
END
Bước 2: Đưa Stored Procedure vào mô hình LINQ to SQL
Bước 3: Gọi thủ tục thêm dữ liệu
< DataContext_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>);
2.7.3. Xóa dữ liệu
Để xóa bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL kết hợp với Stored
Procedure gồm các bước sau:
Bước 1: Tạo thủ tục xóa trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
DELETE FROM <Table_name>
Where Field_Name1=@VField_Name1 and
Field_Name1=@VField_Name2 … and …
Field_Namen=@VField_Namen
END
Bước 2: Đưa Stored Procedure vào mô hình LINQ to SQL.
Bước 3: Gọi thủ tục xóa dữ liệu
<DataContext_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>);
2.7.4. Tìm kiếm thông tin
Để tìm kiếm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua
việc sử dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL kết hợp với
Stored Procedure gồm các bước sau:
Bước 1: Tạo thủ tục tìm kiếm trong SQL Server
- Trường hợp 1: Tìm kiếm có điều kiện
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
Select * FROM <Table_name>
Where Field_Name1=@VField_Name1 and
Field_Name2=@VField_Name2 … and …
Field_Namen=@VField_Namen
END
- Trường hợp 1: Tìm kiếm không điều kiện
50
Tập bài giảng Lập trình cơ sở dữ liệu

CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]


AS
BEGIN
Select * FROM <Table_name>
END
Bước 2: Đưa Stored Procedure vào mô hình LINQ to SQL
Bước 3: Gọi thủ tục tìm kiếm dữ liệu
- Trường hợp 1: Tìm kiếm điều kiện
<DataContext_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>);
- Trường hợp 2: Tìm kiếm không điều kiện
< DataContext_Name >.<StoredProcedure_Name>();
2.7.5. Sửa dữ liệu
Để sửa bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình LINQ to SQL kết hợp với Stored
Procedure gồm các bước sau:
Bước 1: Tạo thủ tục cập nhật trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
UPDATE <Table_name>
Set Field_Name1=@VField_Name1,..,Field_Namen=@VField_Namen
Where Field_Namek=@VField_Namek
END
Bước 2: Đưa Stored Procedure vào mô hình LINQ to SQL.
Bước 3: Gọi thủ tục sửa dữ liệu
< DataContext_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>);
2.7.6. Các ví dụ
Ví dụ 2.18. Form quản lý phiếu nhập hàng có mẫu sau. Sử dụng mô hình LINQ to
SQL kết hợp với Stored Procedure để thực hiện quản lý các phiếu nhập.

51
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 2.13. Form quản lý phiếu nhập hàng.


Bước 1: Tạo các Stored Procedure
Bước 2: Đưa Stored Procedure vào mô hình LINQ to SQL
Bước 3: Tạo và thiết kế Form Quản lý phiếu xuất hàng
STT Đối tượng Thuộc tính Giá trị
Name frm_PN
1 Form
Text Quản lý phiếu nhập hàng
2 Label Text Mã nhà cung cấp
3 Label Text Tên nhà cung cấp
4 Label Text Số phiếu
5 Label Text Ngày nhập
6 GroupBox Text Thông tin phiếu nhập
7 GroupBox Text Danh sách phiếu nhập
8 Combobox Name cbmancc
9 TextBox Name txttenncc
10 TextBox Name txtsoPN
11 DateTimePicker Name dtpNgayN
12 DataGridView Name dg_Hienthi
Name btnThem
13 Button
Image System.Drawing.Bitmap
Name btnHieuchinh
14 Button
Image System.Drawing.Bitmap
Name btnLuu
15 Button
Image System.Drawing.Bitmap
Name btnXoa
16 Button
Image System.Drawing.Bitmap
Name btnTimkiem
17 Button
Image System.Drawing.Bitmap
Bước 4: Khai báo các tham số
QLKDDataContext qlkdDC;
int iu;
Bước 5: Lập trình các phương thức:
52
Tập bài giảng Lập trình cơ sở dữ liệu

1) Phương thức hiện thị trên lưới


void Show_GridView()
{
var query = qlkdDC.sp_SelectPN();
dg_Hienthi.DataSource = query.ToList();
}
2) Phương thức làm trắng các TextBox
private void Set_Empty()
{
txtSoPN.Text = "";
txtTenncc.Text = "";
}
3) Phương thức hiển thị mã nhà cung cấp lên Combobox
private void Load_Combobox()
{
var query = qlkdDC.sp_SelectNCC();
cbmancc.DataSource = query.ToList();
cbmancc.DisplayMember = "mancc";
}
Bước 6: Lập trình sự kiện Load của form frm_PN
private void frm_PX_Load(object sender, EventArgs e)
{
qlkdDC = new QLKDDataContext();
dg_Hienthi.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
Load_Combobox();
Show_GridView();
}
Bước 7: Lập trình sự kiện các nút
1) Sự kiện Click nút btnThem
private void btnThem_Click(object sender, EventArgs e)
{
iu = 0;
Set_Empty();
btnLuu.Enabled = true;
btnThem.Enabled = false;
}
2) Sự kiện Click nút btnHieuchinh
private void btnHieuchinh_Click(object sender, EventArgs e)
{
iu = 1;
btnLuu.Enabled = true;
btnHieuchinh.Enabled = false;
txtSoPN.Enabled = false;
}
3) Sự kiện Click nút btnLuu
private void btnLuu_Click(object sender, EventArgs e)
{
if (txtSoPN.Text != "" && txtTenncc.Text != "")
{
if (iu == 0)
{
int dem = qlkdDC.sp_SearchPN(txtSoPN.Text).Count();
if (dem == 0)

53
Tập bài giảng Lập trình cơ sở dữ liệu

{
qlkdDC.sp_InsertPN(txtSoPN.Text, cbmancc.Text,
dtpNgayN.Value);
MessageBox.Show("Thêm mới thành công", "Thông
báo");
}
else MessageBox.Show("Trùng mã phiếu nhập", "Thông
báo");
}
else
{
qlkdDC.sp_UpdatePN(txtSoPN.Text, cbmancc.Text,
dtpNgayN.Value);
MessageBox.Show("Cập nhật thành công", "Thông báo");
}
btnLuu.Enabled = false;
btnThem.Enabled = true;
btnHieuchinh.Enabled = true;
txtSoPN.Enabled = true;
Show_GridView();
}
else
{
MessageBox.Show("Dữ liệu nhập chưa hợp lệ", "Thông
báo");
}
}
4) Sự kiện Click nút btXoa
private void btnXoa_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
qlkdDC.sp_DeletePN(txtSoPN.Text);
qlkdDC.SubmitChanges();
MessageBox.Show("Xóa thành công", "Thông báo");
Show_GridView();
}
}
4) Sự kiện Click nút btnTimKiem
Bước 8: Lập trình sự kiện SelectionChanged của DataGridView dg_Hienthi
private void dg_Hienthi_SelectionChanged(object sender, EventArgs e)
{
if (dg_Hienthi.SelectedRows.Count > 0)
{
txtSoPN.Text = dg_Hienthi.CurrentRow.Cells[0].Value.ToString();
cbmancc.Text = dg_Hienthi.CurrentRow.Cells[1].Value.ToString();
dtpNgayN.Value =
DateTime.Parse(dg_Hienthi.CurrentRow.Cells[2].Value.ToString());
}
}
Bước 9: Lập trình sự kiện SelectedIndexChanged của Combobox cbmancc
private void cbmancc_SelectedIndexChanged(object sender, EventArgs e)
{

54
Tập bài giảng Lập trình cơ sở dữ liệu

var query = qlkdDC.sp_SearchNCC(cbmancc.Text).ToList();


if(query.Count()>0)
txtTenncc.Text = query.First().Tenncc;
}

CHƯƠNG 3: LẬP TRÌNH CƠ SỞ DỮ LIỆU SỬ DỤNG ADO.NET ENTITY


DATA MODEL

3.1. Mô hình Entity Data Model (EDM)


3.1.1. Các khái niệm
ADO.NET Entity Framework là một nền tảng được sử dụng để làm việc với các cơ
sở dữ liệu thông qua cơ chế ánh xạ Object/Relational Mapping (ORM). Nhờ đó, bạn có
thể truy vấn, thao tác với database gián tiếp thông qua các đối tượng lập trình.
Kiến trúc của Entity Framework được minh họa như sau:

Hình 3.1. Kiến trúc của Entity Framework.


LINQ to Entities: LINQ to Entities is a query language used to write queries against
the object model. It returns entities, which are defined in the conceptual model. You can
use your LINQ skills here.
LINQ to Entities: là ngôn ngữ truy vấn LINQ được dùng để sinh ra các truy vấn trên
mô hình đối tượng và trả về các thực thể được định nghĩa trong mô hình đối tượng.
Entity SQL: là ngôn ngữ truy vấn giống như LINQ to Entities
Object Service: Là lớp được dùng để truy xuất và cập nhật dữ liệu từ cơ sở dữ liệu,
chịu trách nhiệm chuyển đổi dữ liệu được trả về từ nguồn dữ liệu khách sang cấu trúc
đối tượng thực thể.
Entity Client Data Provider: chuyển đổi LINQ to Entities hoặc Entity SQL thành truy
vấn SQL và kết nối với the ADO.Net data provider để thực hiện nhận hoặc gửi dữ liệu
với cơ sở dữ liệu
ADO.Net Data Provider: chịu trách nhiệm kết nối với cơ sở dữ liệu sử dụng chuẩn
ADO.Net.
Entity Data Model (EDM) là mô hình dữ liệu được mô tả thông qua các ngôn ngữ
theo chuẩn XML. EDM được chia làm 3 lớp là: Conceptual, Mapping và Storage. Mỗi
lớp này được định nghĩa bởi ngôn ngữ riêng theo định dạng XML:
55
Tập bài giảng Lập trình cơ sở dữ liệu

- Conceptual Model: chứa các lớp thực thể và các mối quan hệ giữa các lớp. Mô hình
này độc lập với thiết kế của cơ sở dữ liệu
- Storage Model: chứa mô hình thiết kế cơ sở dữ liệu bao gồm các bảng thủ tục, khóa,
các view và mối quan hệ giữa các bảng.
- Mapping: chứa thông tin ánh xạ giữa Conceptual Model và Storage Model
EDM là một mô hình dữ liệu phía máy khách và là thành phần chính của Entity
Framework. EDM không giống như các mô hình cơ sở dữ liệu, mà thuộc về cơ sở dữ
liệu. Mô hình dữ liệu trong ứng dụng mô tả cấu trúc của các đối tượng trong hệ thống,
cho phép tái cấu trúc các bảng và các views trong cơ sở dữ liệu để các bảng và các mối
quan hệ giống như đối tượng trong hệ thống chứ không phải là mô hình quan hệ được
tạo ra bởi các hệ quản trị cơ sở dữ liệu khác nhau.
EDM là cầu nối giữa các ứng dụng và cơ sở dữ liệu, cho phép làm việc với cơ sở dữ
liệu thông qua lớp dịch vụ được cung cấp bởi Entity Frame-work sử dụng một EDM để
truy vấn hoặc lưu trữ dữ liệu. Các công cụ Entity Framework tạo ra các lớp từ mô hình
này cho phép người sử dụng làm việc với các đối tượng được mô tả trong mô hình EDM.
Như vậy có thể thấy rằng LINQ to SQL và Entity Data Model đều được dùng để xây
dựng các ứng dung truy xuất dư liệu nhưng EDM có phạm vi sử dụng hơn trên các hệ
quản trị khác nhau. Bảng sau so sánh sự khác nhau giữa LINQ to SQL và EDM.
LINQ to SQL Entity Data Model

Chỉ làm việc với SQL Server Làm việc với nhiều hệ quản trị cơ sở dữ
liệu khác nhau: Oracle, DB2, MYSQL,
SQL Server, …

Sinh ra tập tin *.dbml để mô tả các Sinh ra tập tin *.edmx và cac mối liên hệ,
tập thực thể và các mối liên hệ tập thực thẻ được mô tả trong ba tập tin
khác nhau .csdl, .msl, ssdl.

Không hỗ trợ kiểu dữ liệu phức hợp Hỗ trợ kiểu dữ liệu phức hợp

Không thể sinh ra cơ sở dữ liệu từ mô Có thể sinh ra cơ sở dữ liệu từ mô hình


hình

Chỉ cho phép anh xạ 1-1 giữa các tập Cho phép ánh xạ 1-1, 1-n, n-n giữa các
thực thể và các bảng quan hệ hoặc các tập thực thể và các bảng quan hệ hoặc các
view. view.

Truy vấn dữ liệu sử dụng Truy vấn dữ liệu sử dụng EntitySQL,


DataContext ObjectContext, DbContext.
Các phương pháp tạo mô hình EDM:
- Sử dụng Entity Data Model Wizard
- Sử dụng Entity Data Model Design
Hình 3.2 là một mô hình cơ sở dữ liệu quan hệ được thiết kế bằng một hệ quản trị cơ
sở dữ liệu giữa ban bảng PersonalDetails, Person, SalesPerson.

56
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.2. Mô hình cơ sở dữ liệu quan hệ


Do đó, câu truy vấn để lấy thông tin chi tiết của người bán hàng sử dụng T-SQL như
sau:
SELECT SalesPerson.*, PersonalDetails.*, Person.*
FROM Person INNER JOIN PersonalDetails ON
Person.PersonID = PersonalDetails.PersonID
INNER JOIN SalesPerson ON
Person.PersonID = SalesPerson.PersonID
Hình 3.3 là một mô hình EDM.

Hình 3.3. Mô hình EDM có tên Northwind.


Do đó, câu truy vấn để lấy thông tin chi tiết của người bán hàng sử dụng mô hình
EDM như sau:
var PersonQuery = from p in Northwind.Persons where
p.FirstName.Contains(“J”) select p;
Person CurrenPer = PersonQuery.First();
3.1.2. Các thành phần của mô hình EDM
- Tập thực thể
- Các thuộc tính của tập thực thể
+ Thuộc tính mô tả
+ Thuộc tính khóa
+ Thuộc tính kết nối
Tập thực thể

Thuộc tính khóa

Thuộc tính mô tả

Thuộc tính kết nối


57
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.4. Tập thực thể khách hàng và các thuộc tính
- Các mối liên hệ giữa các tập thực thể
+ Mối liên hệ 1-1
+ Mối liên hệ 1-n

Hình 3.5. Mối liên hệ giữa các tập thực thể


3.1.3. Ánh xạ giữa tập thực thể với bảng hoặc view
Để sử dụng mô hình EDM trong lập trình cơ sở dữ liệu, phải luôn đảm bảo ánh xạ
giữa tập thực thể vầ bảng hoặc View trong SQL Server.

58
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.6. Ánh xạ giữa tập thực thể và bảng khách hàng
3.2. Thiết kế mô hình EDM bằng công cụ Designer
3.2.1. Tạo mới mô hình EDM
Bước 1: Chọn chuột phải dự án/Chọn Add/Chọn New Item

Hình 3.7. Tạo mới mô hình EDM


Bước 2: Chọn ADO.NET Entity Data Model/Nhập tên tại mục Name/Chọn Add

Hình 3.8. Nhập tên mô hình EDM


Bước 3: Chọn Empty model/Chọn Finish

59
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.9. Chọn mô hình thiết kế EDM

Sau khi tạo xong một mô hình EDM thì mô hình được lưu lại với file có phần mở
rộng là *.edmx

Hình 3.10. Môi trường để thiết kế mô hình EDM


3.2.2. Thêm mới, xóa một tập thực thể
1) Thêm mới một tập thực thể
Bước 1: Chọn chuột phải trên môi trường để thiết kế mô hình EDM/Chọn Add/Chọn
Entity

Hình 3.11. Tạo mới một tập thực thể


60
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 2: Thiết lập các thuộc tính cơ bản cho tập thực thể
- Nhập tên tập thực thể tại mục Entity name
- Tạo khóa cho tập thực thể:
+ Chọn mục Create Key property
+ Nhập tên cho thuộc tính khóa tại mục Property name
+ Chọn kiểu dữ kiệu cho thuộc tính khóa tại mục Property type
+ Chọn OK

Hình 3.12. Thiết lập các thuộc tính cho tập thực thể
Sau khi tạo xong, ta được hình ảnh của tập thực thể

Hình 3.13. Tập thực thể sinh viên


2) Xóa một tập thực thể
Chọn chuột phải trên tập thực thể/Chọn Delete from Model

61
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.14. Xóa tập thực thể


3.2.3. Thêm, sửa, xóa, các thuộc tính
1) Thêm mới thuộc tính
Bước 1: Chọn chuột phải trên tập thực thể/Chọn Add New/Chọn Scalar Property

Hình 3.15. Tạo mới một thuộc tính


Bước 2: Nhập tên cho thuộc tính

Hình 3.16. Nhập tên cho thuộc tính


Sau khi thêm xong các thuộc tính, ta được hình ảnh của tập thực thể

Hình 3.17. Tập thực thể sinh viên với đầy đủ các thuộc tính
2) Sửa thuộc tính
Bước 1: Chọn chuột phải vào tên thuộc tính/Chọn Properties

62
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.18. Thiết lập các thuộc tính cho thuộc tính của tập thực thể
Bước 2: Gán giá trị cho các thuộc tính
- Getter: Dùng để lấy giá trị của thuộc tính gồm 3 kiểu (Public, Private, Protected,
Internal)
- Settter: Dùng để gán giá trị cho thuộc tính gồm 3 kiểu (Public, Private, Protected,
Internal)
- Type: Xác định kiểu dữ liệu của thuộc tính
- Name: Xác định tên của thuộc tính
- Default Value: Xác định giá trị mặc định của thuộc tính
- Entity key: Xác định thuộc tính có là khóa của tập thực thể không (True/False)
- Fixed Length: Xác định độ dài tối đa của thuộc tính

Hình 3.19. Thiết lập các thuộc tính cho thuộc tính của tập thực thể
3) Xóa thuộc tính
Chọn chuột phải vào tên thuộc tính/Chọn Delete from Model

63
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.20. Xóa thuộc tính của tập thực thể


3.2.4. Thêm, sửa, xóa các mối liên hệ
1) Thêm mối liên hệ
Bước 1: Trên Toolbox chọn Association

Hình 3.21. Chọn đối tượng tạo mối liên hệ


Bước 2: Chọn thuộc tính khóa bên một kéo thả vào thuộc tính kết nối bên nhiều

Hình 3.22. Xác định thuộc tính kết nối giữa hai tập thực thể
Sau khi tạo xong mối liên hệ, có kết quả:

Hình 3.23. Mối liên hệ giữa hai tập thực thể


2) Sửa mối liên hệ
Bước 1: Chọn mối liên hệ/Chọn Properties

64
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.24. Sửa mối liên hệ giữa hai tập thực thể
Bước 2: Thay đổi các thuộc tính của mối liên hệ giữa hai tập thực thể
- End1 Multiplicity: Xác định tập thực thể bên một -1(One of Tên tập thực thể)
- End2 Multiplicity: Xác định tập thực thể bên nhiều -* (Collection of Tên tập thực
thể)
- Name: Xác định tên mối liên hệ
- End1 Role Name: Xác định tên tập thực thể bên một
- End 2 Role Name: Xác định tên tập thực thể bên nhiều
- End 1 OnDelete: Xác định có xóa các thực thể của tập thực thể bên một mà nó so
khớp với các thực thể bên nhiều (None-Không/Cascade-có)
- End 2 OnDelete: Xác định có xóa các thực thể của tập thực thể bên nhiều mà nó so
khớp với các thực thể bên một (None/Cascade)

Hình 3.25. Thay đổi các thuộc tính của mối liên hệ giữa hai tập thực thể
3) Xóa mối liên hệ
Chọn mối liên hệ/Chọn Delete from Model

Hình 3.26. Xóa mối liên hệ giữa hai tập thực thể
65
Tập bài giảng Lập trình cơ sở dữ liệu

3.3. Thiết kế mô hình EDM bằng công cụ Wizard


Bước 1: Chọn chuột phải dự án/Chọn Add/Chọn New Item

Hình 3.27. Tạo mới mô hình EDM


Bước 2: Chọn ADO.NET Entity Data Model/Nhập tên tại mục Name/Chọn Add

Hình 3.28. Nhập tên cho mô hình EDM


Bước 3: Chọn Gennerate from Database/Chọn Next

66
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.29. Dịch ra mô hình EDM từ Database


Bước 4: Chọn New Connection

Hình 3.30. Kết nối đến Database nguồn


Bước 5: Chọn cơ sở dữ liệu nguồn:
- Nhập tên Server tại mục Server Name
- Chọn chế độ đăng nhập tại mục Log on to the Server:
+ Trường hợp 1: Đăng nhập bằng tài khoản Window thì chọn Use Window
Authentication
+ Trường hợp 2: Đăng nhập bằng tài khoản SQL Server thì chọn Use SQL Server
Authentication/Nhập tên User Name/Nhập Passwork
67
Tập bài giảng Lập trình cơ sở dữ liệu

- Chọn cơ sở dữ liệu tại mục Select or Enter Database Name/OK

Hình 3.31. Chọn cơ sở dữ liệu nguồn


Bước 6: Chọn chuỗi kết nối cho mô hình EDM
- Chọn Save entity connection settings in App.config as/Nhập tên cho chuỗi kết nối
- Chọn Next

Hình 3.32. Chọn chuỗi kết nối cho mô hình EDM


Bước 7: Chọn đối tượng trong cơ sở dữ liệu cho mô hình EDM:
- Chọn Table hoặc View hoặc Stored Procedure
- Nhập Namespace cho mô hình tại mục Model Namespace
- Chọn Finish
68
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.33. Chọn đối tượng trong Database cho mô hình EDM
Sau khi tạo xong, có mô hình EDM:

Hình 3.34. Mô hình EDM cho cơ sở dữ liệu QLKD


3.4. Cập nhật mô hình EDM từ cơ sở dữ liệu
Bước 1: Trong cửa sổ EDM Designer của file *.edmx/Chọn chuột phải/Chọn Update
Model from Database.

69
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.35. Chọn chế độ cập nhật mô hình EDM


Bước 2: Chọn đối tượng cần cập nhật (đưa bổ sung vào mô hình)/Chọn Finish

Hình 3.36. Chọn đối tượng cần cập nhật

Hình 3.37. Kết quả cập nhật mô hình EDM


70
Tập bài giảng Lập trình cơ sở dữ liệu

3.5. Sinh cơ sở dữ liệu từ mô hình EDM


Bước 1: Trong cửa sổ EDM Designer của file *.edmx/Chọn chuột phải/Chọn
Generate Database from Model.

Hình 3.38. Sinh cơ sở dữ liệu từ mô hình EDM


Bước 2: Chọn New Connection

Hình 3.39. Kết nối đến cơ sở dữ liệu đích


Bước 5: Chọn cơ sở dữ liệu đích:
- Nhập tên Server tại mục Server Name
- Chọn chế độ đăng nhập tại mục Log on to the Server:
+ Trường hợp 1: Đăng nhập bằng tài khoản Window thì chọn Use Window
Authentication
+ Trường hợp 2: Đăng nhập bằng tài khoản SQL Server thì chọn Use SQL Server
Authentication/Nhập tên User Name/Nhập Passwork
- Nhập tên cơ sở dữ liệu tại mục Select or Enter Database Name/OK

71
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.40. Chọn cơ sở dữ liệu đích


Bước 6: Chọn Yes

Hình 3.41. Xác nhận tạo một cơ sở dữ liệu


Bước 7: Chọn Yes /Chọn Next

72
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.42. Chọn chuỗi kết nối đến Database


Bước 8: Chọn Finish

Hình 3.43. Xác nhận sinh cơ sở dữ liệu


Bước 9: Sinh bảng trong cơ sở dữ liệu bằng cách kích chọn nút thực thi truy vấn
trong tập tin *.edmx.sql được sinh ra.

73
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.44. Sinh các bảng tương ứng với các thực thể
Sau khi tạo xong, có cơ sở dữ liệu trong SQL Sever:

Hình 3.45. Cơ sở dữ liệu QLD được sinh ra từ mô hình EDM


3.6. Truy vấn cơ sở dữ liệu sử dụng EDM
3.6.1. Khai báo đối tượng EDM
Cú pháp:
[<Access_Range>] <DBContext_Class> <DBContext_Name> = new
<DBContext_Class>;
Trong đó:
- DBContext_Name: Tên của đối tượng lớp DBContext_Class

74
Tập bài giảng Lập trình cơ sở dữ liệu

- DBContext_Class: Lớp con của lớp DBContext được sinh ra tự động khi tạo mô
hình EDM và có tên là <tên tập tin .edmx>Entities.
- Access_Range: Phạm vi truy cập của đối tượng (public, protected, private,… )
Ví dụ:
QLKDEntities qlkd = new QLKDEntities();
3.6.2. Tham chiếu đến phương thức và thuộc tính đối tượng EDM
Cú pháp:
<DBContext_Name>.<Method_Name/Property_Name>
Trong đó:
- Method_Name: Tên của thuộc tính
- Property_Name: Tên của phương thức
Ví dụ:
dg_Hienthi.DataSource = qlkd.sp_PX;
dg_Hienthi.DataSource = qlkd.tbHangs;
3.6.3. Khai báo thực thể
Cú pháp:
[<Access_Range>] <Entities_Class_Name> <Entity_Name> = new
<Entities_Class_Name>;
Trong đó:
- Entity_Name: Tên của thực thể
- Entities_Class_Name: Tên của tập thực thể
Ví dụ:
tbHang newmh = new tbHang();
3.6.4. Lấy thuộc tính của thực thể
Cú pháp:
<Entity_Name> .<Property_Name>
Trong đó: Property_Name: Tên của thuộc tính của thực thể
Ví dụ:
newmh.Mahang = txtMaMH.Text;
3.6.5. Lớp DBContext
Tác dụng: để truy vấn và làm việc với dữ liệu của thực thể như là các đối tượng và
cho phép cập nhật lại dữ liệu nguồn.
1) Các hàm khởi tạo (Constructors)
Name Description
DbContext() Khởi tạo một thể hiện của lớp DBContext.
DbContext(String) Khởi tạo một thể hiện của lớp DBContext
với tên của chuỗi kết nối thực thể hoặc tên
cơ sở dữ liệu.
2) Các thuộc tính
Name Description
Database Tạo một cơ sở dữ liệu cho đối tượng DBContext
và cho phép thực hiện thêm sửa, thêm mới trên
cơ sở dữ liệu
Configuration Hỗ trợ truy cập tới các lựa chọn cấu hình.
3) Các phương thức

75
Tập bài giảng Lập trình cơ sở dữ liệu

Name Description
Set(Type)() Trả về đối tượng lớp DBSet cho một kiểu
cụ thể
Dispose() Giải phóng bộ nhớ
SaveChanges() Lưu trữ tất cả các thay đổi đến dữ liệu
nguồn và cập nhật lại mô hình EDM
3.7. Làm việc với cơ sở dữ liệu sử dụng EDM
3.7.1. Các cách thức truy vấn với EDM
Để truy vấn dữ liệu từ dữ liệu nguồn sử dụng mô hình EDM, Entity Framework hỗ
trợ ba loại truy vấn: 1) LINQ to Entities, 2) Entity SQL và Native SQL. Trong mục này
trình bày cách thức tìm kiếm thực thể theo ba cách trên.
1) LINQ to Entities:
Sử dụng cú pháp truy vấn hoặc cú pháp dạng phương thức LINQ để truy vấn với mô
hình EDM.
Bước 1: Khai báo thực thể lớp cần tìm kiếm
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
Bước 2: Tạo truy vấn tìm kiếm
- Cách 1: sử dụng cú pháp truy vấn
var <Query_Name> = from <Element_Name> in
<DBContext_Name>.<Entity_Class_Name>s
[where <Element_Name>.<Property_Name> = <Value>] select <Element_Name>;
- Cách 2: sử dụng cú pháp dạng phương thức
var <Query_Name> =
<DBContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression);
Bước 3: Trả về thực thể tìm kiếm đầu tiên
<Entity_Name> = <Query_Name>.FirstOrDefault();
Ví dụ:
tbHang hang = new tbHang();
var query = from h in qlkdDB.tbHangs where h.Mahang == txtMaMH.Text
select h;
hang = query.FirstOrDefault();
2) Entity SQL
Entity SQL là ngôn ngữ có cú pháp gần giống với T_SQL được dùng để tạo truy vấn
bằng cách sử dụng Entity Framework’s Object Services và trả về đối tượng lớp
ObjectQuery.
Bước 1: Tạo truy vấn Entity SQL
String <Query_Name> = “SELECT VALUE <Element_Name> FROM <
DBContext_Class>.<Entity_Class_Name>s AS <Element_Name> [WHERE
<Element_Name>.<Property_Name> == @<Parameter_Name>]”;
Bước 2: Tạo đối tượng lớp ObjectContext
ObjectContext <ObjectContext_Name> = (<DBContext_Name> as
IObjectContextAdapter).ObjectContext;
Bước 3: Tạo đối tượng ObjectQuery
ObjectQuery<<Entity_Class_Name>> <ObjectQuery_Name> =
<ObjectContext_Name>. CreateQuery<<Entity_Class_Name>>(<Query_Name>);
Nếu truy vấn có tham số thì phải thêm tham số vào đối tượng ObjectQuery như sau:
[<ObjectQuery_Name>.Parameters.Add(New
ObjectParameter("<Parameter_Name>", <Value>))];
Bước 4: Khai báo thực thể lớp cần tìm kiếm
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
76
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 5: Trả về thực thể tìm kiếm đầu tiên


<Entity_Name> = <ObjectQuery_Name>.FirstOrDefault();
Ví dụ:
string sql = "SELECT VALUE st FROM QLKDEntities.tbHangs AS st WHERE
st.Mahang == @mahang";
ObjectContext qlkdOC = (qlkdDB as IObjectContextAdapter).ObjectContext;
ObjectQuery<tbHang> oq = qlkdOC.CreateQuery<tbHang>(sql);
oq.Parameters.Add(new ObjectParameter("mahang", txtMaMH.Text));
tbHang hang = oq.FirstOrDefault();
3) Native SQL
Sử dụng SQL để truy vấn dữ liệu từ dữ liệu nguồn
Bước 1: Tạo truy vấn Entity SQL
string <SQL_Command> = "SELECT [  <Fields  Expression>]FROM
<Table_Name> WHERE <Search_Condition>";
Bước 2: Khai báo thực thể lớp cần tìm kiếm
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
Bước 3: Trả về thực thể tìm kiếm đầu tiên
<Entity_Name> =
<DBContext_Name>.SqlQuery(<SQL_Command>).FirstOrDefault<<Entity_Class_Na
me>>();
Nếu truy vấn có tham số thì cần phải tạo đối tương tham số lớp SqlParameter trước
khi trả về thực thể tìm kiếm như sau:
SqlParameter <SqlParameter_Name> = new SqlParameter(“@<Parameter_Name>”,
Value);
<Entity_Name> = <DBContext_Name>.SqlQuery(<SQL_Command>,
<SqlParameter_Name>).FirstOrDefault<<Entity_Class_Name>>();
Ví dụ:
tbHang hang = new tbHang();
string sql = "select * from tbhang where mahang = @mahang";
SqlParameter sp = new SqlParameter("@mahang", txtMaMH.Text);
hang = qlkdDB.tbHangs.SqlQuery(sql, sp).FirstOrDefault<tbHang>();
Trên đây là các cách thức truy vấn dữ liệu sử dụng mô hình EDM, với các thức sử
dụng Entity SQl và Native SQL, người đọc tự tìm hiểu thêm. Trong phần còn lại của
giáo trình sẽ sử dung LINQ to Entities để thực hiện các thao tác tìm kiếm, thêm, sửa,
xóa từ dữ liệu nguồn.
3.7.2. Thêm dữ liệu
Để thêm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc
sử dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM ta gồm các bước sau:
Bước 1: Khai báo một thực thể
[<Access_Range>] Entity_Class_Name <NewEntity_Name> = new
<Entity_Class_Name>();
Bước 2: Gán giá trị cho các thuộc tính của thực thể
<NewEntity_Name>.<Property_Name1>=<Value1>;

<NewEntity_Name>.<Property_Namen>=<Valuen>;
Bước 3: Gọi phương thức thêm một thực thể vào tập thực thể
<DBContext_Name>.<Entity_Class_Name>s.Add(<NewEntity_Name>);
Bước 4: Lưu lại các thay đổi của tập thực thể
<DBContext_Name>.SaveChanges();
Ví dụ:
tbHang newmh = new tbHang();
77
Tập bài giảng Lập trình cơ sở dữ liệu

newmh.Mahang = txtMaMH.Text;
newmh.Tenhang = txtTenMH.Text;
newmh.Dvt = txtDVT.Text;
qlkd. tbHangs.Add(newmh);
qlkd.SaveChanges();
3.7.3. Xóa dữ liệu
Để xóa bản ghi từ bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM ta gồm các bước sau:
Bước 1: Khai báo một thực thể để xóa
[<Access_Range>] <Entity_Class_Name> <CurrentEntity_Name> = new
<Entity_Class_Name>();
Bước 2: Tạo truy vấn tìm kiếm
- Cách 1: sử dụng cú pháp truy vấn
var <Query_Name> = from <Element_Name> in
<DBContext_Class>.<Entity_Class_Name>s
[where <Element_Name>.<Property_Name> = <Value>] select <Element_Name>;
- Cách 2: sử dụng cú pháp dạng phương thức
var <Query_Name> =
<DBContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression);
Bước 3: Trả về thực thể tìm kiếm đầu tiên
<Entity_Name> = <Query_Name>.FirstOrDefault();
Bước 4: Gọi phương thức xóa thực thể
<DBContext_Name>.<Entity_Class_Name>s.Remove(<CurrentEntity_Name>);
Bước 5: Lưu lại thay đổi sau khi xóa
<DBContext_Name>.SaveChanges();
<CurrentEntity_Name> = null;
Ví dụ:
tbHang hang = new tbHang();
var query = qlkdDB.tbHangs.Where<tbHang>(n => n.Mahang ==
txtMaMH.Text);
hang = query.FirstOrDefault();
qlkdDB.tbHangs.Remove(hang);
qlkdDB.SaveChanges();
hang = null;
3.7.4. Tìm kiếm thông tin
Để tìm kiếm thông tin trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ cơ sở dữ liệu trong mô hình EDM gồm các trường hợp
và các bước sau:
1) Tìm kiếm không điều kiện
- Đưa dữ liệu lên combox
<ComboBoxName>.DataSource = <DBContext_Name>.<Entity_Class_Name>s
<ComboBoxName>.DisplayMember = "<FieldName>"
<ComboBoxName>.ValueMember = "<FieldName>"
Ví dụ:
cbMahang.DataSource = qlkdDB.tbHangs.ToList();
cbMahang.DisplayMember = "tenhang";
cbMahang.ValueMember = "mahang";
- Đưa dữ liệu lên DataGridView:
<DataGridView_Name>.DataSource =
<DBContext_Name>.<Entity_Class_Name>s;
Ví dụ:
78
Tập bài giảng Lập trình cơ sở dữ liệu

dg_Hienthi.DataSource = qlkdDB.tbHangs.ToList();
2) Tìm kiếm có điều kiện
- Cách 1: sử dụng cú pháp truy vấn
var <Query_Name> = from <Element_Name> in
<DBContext_Class>.<Entity_Class_Name>s
[where <Element_Name>.<Property_Name> = <Value>] select <Element_Name>;
- Cách 2: sử dụng cú pháp dạng phương thức
var <Query_Name> =
<DBContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression);
- Hiện thị dữ liệu lên các đối tượng trên form
+ Trên Combox:
<ComboBoxName>.DataSource = <Query_Name>.ToList();
<ComboBoxName>.DisplayMember = "<FieldName>";
<ComboBoxName>.ValueMember = "<FieldName>";
+ Trên DataGridView:
<DataGridViewName>.DataSource = <Query_Name>.ToList();
Ví dụ:
var khQuery = from n in qlkdDB.tbKhachs select n;
//Hiện thị trên Combox
cbkh.DataSource= khQuery.ToList();
cbkh.DisplayMember = "Tenkh";
cbkh.ValueMember = "Makh";
//Hiện thị trên DataGridView
dg_Hienthi.DataSource = khQuery.ToList();
3.7.4. Sửa dữ liệu
Để sửa bản ghi từ bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM ta gồm các bước sau:
Bước 1: Lấy ra thực thể cần sửa
- Khai báo thực thể lớp cần sửa
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
- Tìm đối tượng cần sửa và gán cho đối tượng thực thể
Cách 1: Sử dụng cú pháp dạng phương thức
var <Query_Name>
=<DBContext_Name>.<Entity_Class_Name>s.Where(Lambda_Expression);
Cách 2: Sử dụng cú pháp truy vấn
var <Query_Name> = from <Element_Name> in
<DBContext_Name>.<Entity_Class_Name>s where <Search_Expresion> select
<Element_Name>;
- Gán đối tượng đầu tiên tìm thấy cho thực thể cần xóa
<Entity_Name> = <Query_Name>.FirstOrDefault();
Bước 3: Gán giá trị cho các thuộc tính của thực thể
<Entity_Name>.<Property_Name1>=<Value1>

<Entity_Name>.<Property_Namen>=<Valuen>
Bước 4: Lưu lại các thay đổi của tập thực thể vào cơ sở dữ liệu
<DBContext_Name>.SaveChanges();
Ví dụ: Cập nhật một bản ghi bảng tbHang có mã mặt hàng “MMH01”
tbHang hang = new tbHang();
var hQuery = qlkdDB.tbHangs.Where(n => n.Mahang == "MMH01");
hang = hQuery.FirstOrDefault();
hang.Dvt = txtDVT.Text;

79
Tập bài giảng Lập trình cơ sở dữ liệu

hang.Tenhang = txtTenMH.Text;
qlkdDB.SaveChanges();
3.7.5. Các ví dụ
Ví dụ 3.2. Form quản lý danh mục các khách hàng mẫu sau. Hãy sử dụng mô hình
EDM để thực hiện việc thêm, hiệu chỉnh, xóa, tìm kiếm thông tin của khách hàng.

Hình 3.46. Giao diện form quản lý khách hàng


Bước 1: Tạo và thiết kế Form Quản lý danh mục các mặt hàng
STT Đối tượng Thuộc tính Giá trị
Name frmKH
1 Form
Text Quản lý khách hàng
2 Label Text Mã khách hàng
3 Label Text Tên khách hàng
4 Label Text Địa chỉ
5 GroupBox Text Thông tin khách hàng
6 GroupBox Text Danh sách khách hàng
7 TextBox Name txtMaKH
8 TextBox Name txtTenKH
9 TextBox Name txtDC
10 DataGridView Name dg_Hienthi
Name btnThem
11 Button
Image System.Drawing.Bitmap
Name btnHieuchinh
12 Button
Image System.Drawing.Bitmap
Name btnLuu
13 Button
Image System.Drawing.Bitmap
Name btnXoa
14 Button
Image System.Drawing.Bitmap
Name btnTimkiem
15 Button
Image System.Drawing.Bitmap
Bước 2: Khai báo các biến và đối tượng
QLKDEntities qlkdDB = new QLKDEntities();
int iu;
tbKhach currentKhach = new tbKhach();
Bước 3: Lập trình các phương thức
1) Phương thức hiện thị trên lưới
80
Tập bài giảng Lập trình cơ sở dữ liệu

void Show_GridView()
{
var query = from n in qlkdDB.tbKhaches select n;
dg_Hienthi.DataSource = query.ToList();
}
2) Phương thức làm trắng các TextBox
private void Set_Empty()
{
txtMaKH.Text = "";
txtTenKH.Text = "";
txtDC.Text = "";
}
3) Phương thức trả về thực thể khách hàng theo mã khách hàng
private tbKhach Get_Current(string makhach)
{
tbKhach temp = new tbKhach();
temp = qlkdDB.tbKhaches.Where<tbKhach>(n => n.Makh ==
makhach).FirstOrDefault();
return temp;
}
4) Phương thức tạo mới một khách hàng
private tbKhach Get_New()
{
tbKhach newKhach = new tbKhach();
newKhach.Makh = txtMaKH.Text;
newKhach.Tenkh = txtTenKH.Text;
newKhach.Diachi = txtDC.Text;
return newKhach;
}
Bước 4: Lập trình sự kiện các điều khiển
1) Lập trình sự kiện Click của nút Thêm
private void btnThem_Click(object sender, EventArgs e)
{
iu = 0;
Set_Empty();
btnLuu.Enabled = true;
btnThem.Enabled = false;
}
2) Lập trình sự kiện Click của nút Hiệu chỉnh
private void btnHieuchinh_Click(object sender, EventArgs e)
{
iu = 1;
btnLuu.Enabled = true;
btnHieuchinh.Enabled = false;
txtMaKH.Enabled = false;
}
3) Lập trình sự kiện Click của nút Xóa
private void btnXoa_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
tbKhach hang = new tbKhach();

81
Tập bài giảng Lập trình cơ sở dữ liệu

var query = qlkdDB.tbKhaches.Where<tbKhach>(n => n.Makh


== txtMaKH.Text);
hang = query.FirstOrDefault();
if (currentKhach != null)
{
qlkdDB.tbKhaches.Remove(hang);
qlkdDB.SaveChanges();
MessageBox.Show("Xóa thành công", "Thông báo");
Show_GridView();
}
}
}
4) Lập trình sự kiện Click của nút Lưu
private void btnLuu_Click(object sender, EventArgs e)
{
if (txtMaKH.Text != "" && txtTenKH.Text != "" && txtDC.Text
!= "")
{
if (iu == 0)
{
currentKhach = Get_Current(txtMaKH.Text);
if (currentKhach == null)
{
tbKhach newKhach = Get_New();
qlkdDB.tbKhaches.Add(newKhach);
qlkdDB.SaveChanges();
MessageBox.Show("Thêm mới thành công", "Thông
báo");
}
else MessageBox.Show("Trùng mã khách hàng", "Thông
báo");
}
else
{
currentKhach = Get_Current(txtMaKH.Text);
currentKhach.Diachi = txtDC.Text;
currentKhach.Tenkh = txtTenKH.Text;
qlkdDB.SaveChanges();
MessageBox.Show("Cập nhật thành công", "Thông báo");
}
btnLuu.Enabled = false;
btnThem.Enabled = true;
btnHieuchinh.Enabled = true;
txtMaKH.Enabled = true;
Show_GridView();
}
else
{
MessageBox.Show("Dữ liệu nhập chưa hợp lệ", "Thông
báo");
}
}
5) Lập trình sự kiện Click nút Tìm kiếm
private void btnTimkiem_Click(object sender, EventArgs e)
{
82
Tập bài giảng Lập trình cơ sở dữ liệu

var query = from n in qlkdDB.tbKhaches


where n.Makh == txtMaKH.Text
select n;
dg_Hienthi.DataSource = query.ToList();
}
6) Lập trình sự kiện SelectionChanged của DataGridView
private void dg_Hienthi_SelectionChanged(object sender, EventArgs e)
{
if (dg_Hienthi.SelectedRows.Count > 0)
{
txtMaKH.Text = dg_Hienthi.CurrentRow.Cells[0].Value.ToString();
txtTenKH.Text = dg_Hienthi.CurrentRow.Cells[1].Value.ToString();
txtDC.Text = dg_Hienthi.CurrentRow.Cells[2].Value.ToString();
}
}
7) Lập trình sự kiện Load của Form frmKH
private void frmKH_Load(object sender, EventArgs e)
{
Show_GridView();
}
Ví dụ 3.3. Form quản lý phiếu xuất hàng có mẫu sau. Sử dụng mô hình EDM để thực
hiện việc xuất hàng.

Hình 3.47. Giao diện quản lý phiếu xuất hàng


Bước 1: Tạo và thiết kế Form Quản lý phiếu nhập hàng
STT Đối tượng Thuộc tính Giá trị
Name frmXuatHang
1 Form
Text Quản lý phiếu xuất hàng
2 Label Text Mã nhà khách hàng
3 Label Text Tên khách hàng
4 Label Text Địa chỉ khách hàng
5 Label Text Số phiếu
6 Label Text Ngày xuất
Text Thông tin phiếu xuất hàng
7 GroupBox Enabled False
Name gbThongTinPhieuXuatHang
Text Danh sách hàng xuất
8 GroupBox Enabled False
Name gbDanhSachHangXuat
9 GroupBox Text Thông tin khách hàng

83
Tập bài giảng Lập trình cơ sở dữ liệu

STT Đối tượng Thuộc tính Giá trị


Enabled False
Name gbThongTinKhachHang
Text Danh sách mặt hàng
10 GroupBox Enabled False
Name gbDanhSachMatHang
11 ComboBox Name cbMaKH
Name ttxtTenKH
12 TextBox
Enabled False
Name txtDCKH
13 TextBox
Enabled False
14 TextBox Name txtSPXuat
15 DateTimePicker Name dtp_ngayx
16 DataGridView Name dgv_hangx
Name btnThem
Button
17 Image System.Drawing.Bitmap
Name btnLuu
18 Button
Image System.Drawing.Bitmap
19 DataGridView Name dgv_mathang
Bước 2: Tùy chỉnh GroupBox dgv_mathang
- Thêm các cột vào GroupBox dgv_mathang
STT Cột Thuộc tính Giá trị
ColumnType DataGridViewCheckBoxColumn
1 Column1
Text
Column2 Text Mã mặt hàng
2
ColumnType DataGridViewTextBoxColumn
Column3 Text Tên khách hàng
3
ColumnType DataGridViewTextBoxColumn
Column4 Text Đơn vị tính
4
ColumnType DataGridViewTextBoxColumn

Hình 3.48. Tạo các cột cho GroupBox dgv_mathang


- Thiết lập thuộc tính RowHeaderVisible là False

84
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.49. Giao diện GroupBox dgv_mathang sau khi tùy chỉnh.
Bước 3: Khai báo các đối tượng
QLKDEntities qlkdDB = new QLKDEntities();
List<string> mhlist = new List<string>();
Bước 4: Lập trình các phương thức:
1) Phương thức thêm mã hàng và tên hàng vào lưới mặt hàng xuất
void PopulateDataGridView(string ma, string ten)
{
dgv_hangx.Rows.Add(ma, ten);
}
3) Phương thức thêm một thực thể vào tập thực thể tbCTPX với dữ liệu là hàng thứ i
trong DataGridView dgv_hangx
void Insert_CTPX(int i)
{
tbCTPX newctpx = new tbCTPX();
newctpx.SoPX = txtSPXuat.Text;
newctpx.SoTT = txtSPXuat.Text +
dgv_hangx.Rows[i].Cells[0].Value;
newctpx.Mahang = dgv_hangx.Rows[i].Cells[0].Value.ToString();
newctpx.SLX =
int.Parse(dgv_hangx.Rows[i].Cells[2].Value.ToString());
newctpx.DGX =
int.Parse(dgv_hangx.Rows[i].Cells[3].Value.ToString());
qlkdDB.tbCTPXes.Add(newctpx);
}
4) Phương thức thêm một thực thể vào tập thực thể tbPX
void Insert_PX()
{
tbPX newpx = new tbPX();
newpx.SoPX = txtSPXuat.Text;
newpx.Makh = cbMaKH.Text;
newpx.NgayX = Convert.ToDateTime(dtp_ngayx.Text);
qlkdDB.tbPXes.Add(newpx);
}
5) Phương thức vô hiệu hóa một số điều khiển
void Set_Enable(bool value)
{
btnLuu.Enabled = value;
btnThem.Enabled = !value;
gbThongTinKhachHang.Enabled = value;
gbThongTinPhieuXuatHang.Enabled = value;
gbDanhSachHangXuat.Enabled = value;
gbDanhSachMatHang.Enabled = value;
}
Bước 5: Lập trình sự kiện Click của nút Nhập mới
private void btnThem_Click(object sender, EventArgs e)
{
85
Tập bài giảng Lập trình cơ sở dữ liệu

//Đưa dữ liệu vào combo


cbMaKH.DataSource = qlkdDB.tbKhaches.ToList();
cbMaKH.DisplayMember = "makh";
//Đưa dữ liệu vào danh sách mặt hàng
dgv_mathang.DataSource = qlkdDB.tbHangs.ToList();
Set_Enable(true);
}
Bước 6: Lập trình cho sự kiện Click của nút Lưu
private void btnLuu_Click(object sender, EventArgs e)
{
Set_Enable(false);
dgv_hangx.Rows.Clear();
if( txtSPXuat.Text != "" && cbMaKH.Text != "")
{
Insert_PX();
//Thêm mới thực thể vào tập thực thể CTPX
for(int i = 0;i<=dgv_hangx.Rows.Count - 2;i++)
Insert_CTPX(i);
qlkdDB.SaveChanges();
MessageBox.Show("Đã lưu vào cơ sở dữ liệu", "Thông
báo");
}
}
Bước 7: Lập trình sự kiện SelectedIndexChanged của Combox
private void cbMaKH_SelectedIndexChanged(object sender, EventArgs e)
{
var khQuery = from kh in qlkdDB.tbKhaches where kh.Makh ==
cbMaKH.Text select kh;
tbKhach khach = khQuery.FirstOrDefault();
if(khach!=null)
{
txtTenKH.Text = khach.Tenkh;
txtDCKH.Text = khach.Diachi;
}
}
Bước 8: Lập trình sự kiện CellContentClick của lưới mặt hàng
private void dgv_mathang_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
string mamh =
dgv_mathang.CurrentRow.Cells[1].Value.ToString();
bool checkBoxStatus =
Convert.ToBoolean(dgv_mathang.CurrentCell.EditedFormattedValue);
int index = mhlist.IndexOf(mamh);
if (checkBoxStatus)
{
if (index < 0)
{
PopulateDataGridView(dgv_mathang.CurrentRow.Cells[1].Value.ToString(),
dgv_mathang.CurrentRow.Cells[2].Value.ToString());
mhlist.Add(mamh);
}

86
Tập bài giảng Lập trình cơ sở dữ liệu

}
else
{
if(index >= 0)
{
mhlist.RemoveAt(index);
dgv_hangx.Rows.RemoveAt(index);
}
}
}
}
Bước 9: Sự kiện Load của form frmXuatHang
private void frmXuatHang_Load(object sender, EventArgs e)
{
dgv_mathang.AutoGenerateColumns = false;
}
3.8. Sử dụng EDM kết hợp với Stored Procedure
3.8.1. Đưa Stored Procedure vào mô hình EDM
Bước 1: Trên Designer của file *.edmx/Chọn chuột phải/Chọn Update Model from
Database.

Hình 3.50. Chọn chế độ cập nhật mô hình EDM


Bước 2: Chọn Stored Procedure đưa bổ sung vào mô hình/Chọn Finish

87
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.51. Chọn Stored Procedure cần đưa vào mô hình


Bước 3: Trong Model Browser chọn chuột phải lên Stored Procedure /Chọn Add
Function Import.

Hình 3.52. Thêm hàm ánh xạ cho Stored Procedure


Bước 4: Chọn kiểu dữ liệu trả về của Stored Procedure/chọn OK
- Scalar: Kiểu dữ liệu vô hướng (int, string, ….)
- Entities: Kiểu là một tập thực thể trong mô hình
- Complex: Kiểu dữ liệu phức tạp

88
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.53. Chọn kiểu dữ liệu trả về của Stored Procedure


- Các bước tạo kiểu dữ liệu Complex:
+ Chọn Complex
+ Chọn Get Column Information
+ Create new Complex Type
3.8.2. Ánh xạ Stored Procedure cho tập thực thể trong mô hình EDM
- Bước 1: Chọn chuột phải tên tập thực thể/Chọn Stored Procedure Mapping

Hình 3.54. Ánh xạ Stored Procedure cho tập thực thể


Bước 2: Trong Mapping Detail, chọn Stored Procedure cần ánh xạ (Ánh xạ các thuộc
tính nếu mô hình không tự tham chiếu)

89
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 3.55. Chọn Stored Procedure cần ánh xạ


3.8.3. Thêm dữ liệu
Để thêm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc
sử dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM kết hợp với Stored
Procedure gồm các bước sau:
Bước 1: Tạo thủ tục thêm trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
INSERT INTO <Table_name>(Field_Name1,.., Field_Namen)
VALUES(@VField_Name1,..,@VField_Namen)
END
Bước 2: Đưa Stored Procedure vào mô hình EDM với kiểu dữ liệu trả về là Entities
Bước 3: Ánh xạ Stored Procedure thêm cho thực thể trong mô hình EDM tương ứng
với bảng trong cơ sở dữ liệu SQL Server.
Bước 3: Gọi thủ tục thêm dữ liệu
<NewEntity_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>)
3.8.4. Sửa dữ liệu
Để sửa bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM kết hợp với Stored Procedure
gồm các bước sau:
Bước 1: Tạo thủ tục cập nhật trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
UPDATE <Table_name>
Set Field_Name1=@VField_Name1,..,Field_Namen=@VField_Namen
Where Field_Namek=@VField_Namek
END
Bước 2: Đưa Stored Procedure vào mô hình EDM với kiểu dữ liệu trả về là Entities
Bước 3: Ánh xạ Stored Procedure sửa cho thực thể trong mô hình EDM tương ứng
với bảng trong cơ sở dữ liệu SQL Server.
Bước 3: Gọi thủ tục sửa dữ liệu
90
Tập bài giảng Lập trình cơ sở dữ liệu

<NewEntity_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>)
3.8.5. Xóa dữ liệu
Để xóa bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua việc sử
dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM kết hợp với Stored Procedure
gồm các bước sau:
Bước 1: Tạo thủ tục cập nhật trong SQL Server
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
DELETE FROM <Table_name>
Where Field_Name1=@VField_Name1 and.. and _
Field_Namen=@VField_Namen
END
Bước 2: Đưa Stored Procedure vào mô hình EDM với kiểu dữ liệu trả về là Entities
Bước 3: Ánh xạ Stored Procedure xóa cho thực thể trong mô hình EDM tương ứng
với bảng trong cơ sở dữ liệu SQL Server.
Bước 3: Gọi thủ tục xóa dữ liệu
<NewEntity_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>)
3.8.6. Tìm kiếm thông tin
Để tìm kiếm bản ghi vào bảng trong cơ sở dữ liệu nguồn (SQL Server) thông qua
việc sử dụng tập thực thể được ánh xạ từ bảng trong mô hình EDM kết hợp với Stored
Procedure gồm các bước sau:
Bước 1: Tạo thủ tục tìm kiếm trong SQL Server
- Trường hợp 1: Tìm kiếm có điều kiện
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
@VField_Name1 <Date_Type1>,
….
@VField_Namen <Date_Typen>
AS
BEGIN
Select * FROM <Table_name>
Where Field_Name1=@VField_Name1 and.. and _
Field_Namen=@VField_Namen
END
- Trường hợp 1: Tìm kiếm không điều kiện
CREATE PROCEDURE [dbo].[<StoredProcedure_Name>]
AS
BEGIN
Select * FROM <Table_name>
END
Bước 2: Đưa Stored Procedure vào mô hình EDM với kiểu dữ liệu trả về là Complex
hoặc Scalar
Bước 3: Ánh xạ Stored Procedure tìm kiếm cho thực thể trong mô hình EDM tương
ứng với bảng trong cơ sở dữ liệu SQL Server.
91
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 3: Gọi thủ tục tìm kiếm dữ liệu


- Trường hợp 1: Tìm kiếm điều kiện
<NewEntity_Name>.<StoredProcedure_Name>(<Field_Value1>, _
…,<Field_Valuen>)
- Trường hợp 2: Tìm kiếm không điều kiện
<NewEntity_Name>.<StoredProcedure_Name>()
3.8.7. Ví dụ
Ví dụ 3.7: Form quản lý phiếu xuất hàng có mẫu sau. Sử dụng mô hình EDM kết
hợp với Stored Procedure để thực hiện quản lý các phiếu xuất.

Hình 3.56. Giao diện quản lý phiếu xuất


Bước 1: Tạo các Stored Procedure
STT Tên thủ tục Ý nghĩa
Trả về thông tin bảng
1 sp_SelecttbKhach
tbKhach
2 sp_SelecttbPX Trả về thông tin bảng tbPX
Trả về bản ghi bảng tbPX
3 sp_SearchtbPX
theo trường SoPX
Thêm bản ghi mới vào bảng
4 sp_InserttbPX
tbPX
Cập nhật bản ghi vào bảng
5 sp_UpdatetbPX
tbPX theo trường SoPX
Xóa bản ghi trong bảng
6 sp_DeletetbPX
tbPX theo trường SoPX
Trả về bản ghi bảng
7 sp_SearchtbKhach
tbKhach theo trường SoPX
Bước 2: Đưa Stored Procedure vào mô hình EDM với kiểu dữ liệu trả về phù hợp
Bước 3: Ánh xạ các Stored Procedure cho các tập thực thể trong mô hình EDM
Bước 4: Tạo và thiết kế Form Quản lý phiếu xuất hàng
STT Đối tượng Thuộc tính Giá trị
Name frmPhieuXuat
1 Form
Text Quản lý phiếu xuất hàng
2 Label Text Mã khách hàng
3 Label Text Tên khách hàng
4 Label Text Số phiếu
5 Label Text Ngày xuất
6 GroupBox Text Thông tin phiếu xuất
92
Tập bài giảng Lập trình cơ sở dữ liệu

7 GroupBox Text Danh sách phiếu xuất


8 Combobox Name cbMakh
9 TextBox Name txtTenkh
10 TextBox Name txtsoPX
11 DateTimePicker Name dtpNgayX
12 DataGridView Name dg_Hienthi
Name btnThem
13 Button
Image System.Drawing.Bitmap
Name btnHieuchinh
14 Button
Image System.Drawing.Bitmap
Name btnLuu
15 Button
Image System.Drawing.Bitmap
Name btnXoa
16 Button
Image System.Drawing.Bitmap
Name btnTimkiem
17 Button
Image System.Drawing.Bitmap
Bước 5: Khai báo các đối tượng và biến
QLKDEntities qlkdDB;
int iu;
tbPX currentPX;
Bước 6: Lập trình các phương thức:
1) Phương thức hiện thị trên lưới
void Show_GridView()
{
var PXes = qlkdDB.sp_SelecttbPX();
dg_Hienthi.DataSource = PXes.ToList();
}
2) Phương thức làm trắng các textbox
private void Set_Empty()
{
txtSoPX.Text = "";
dtpNgayX.Value = DateTime.Now;
}
Bước 7: Lập trình cho sự kiện Load Form
private void frmPhieuXuat_Load(object sender, EventArgs e)
{
qlkdDB = new QLKDEntities();
currentPX = new tbPX();
cbmakh.DataSource = qlkdDB.sp_SelecttbKhach();
cbmakh.DisplayMember = "Makh";
Show_GridView();
}
Bước 8: Lập trình sự kiện Click của nút Thêm
private void btnThem_Click(object sender, EventArgs e)
{
iu = 0;
Set_Empty();
btnLuu.Enabled = true;
btnThem.Enabled = false;
}

93
Tập bài giảng Lập trình cơ sở dữ liệu

Bước 9: Lập trình sự kiện Click của nút Hiệu chỉnh


private void btnHieuchinh_Click(object sender, EventArgs e)
{
iu = 1;
btnLuu.Enabled = true;
btnHieuchinh.Enabled = false;
txtSoPX.Enabled = false;
}
Bước 10: Lập trình cho sự kiện Click của nút Lưu
private void btnLuu_Click(object sender, EventArgs e)
{
if (txtSoPX.Text != "")
{
if (iu == 0)
{
var currentPX = qlkdDB.sp_SearchtbPX(txtSoPX.Text);
if (currentPX.Count() == 0)
{
qlkdDB.sp_InserttbPX(txtSoPX.Text, dtpNgayX.Value,
cbmakh.Text);
MessageBox.Show("Thêm mới thành công", "Thông báo");
}
else MessageBox.Show("Trùng mã phiếu xuất", "Thông báo");
}
else
{
qlkdDB.sp_UpdatetbPX(txtSoPX.Text, dtpNgayX.Value,
cbmakh.Text); MessageBox.Show("Cập nhật thành công", "Thông báo");
}
btnLuu.Enabled = false;
btnThem.Enabled = true;
btnHieuchinh.Enabled = true;
txtSoPX.Enabled = true;
Show_GridView();
}
else
{
MessageBox.Show("Dữ liệu nhập chưa hợp lệ", "Thông báo");
}
}
Bước 11: Lập trình sự kiện Click của nút Xóa
if (MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
qlkdDB.sp_DeletetbPX(txtSoPX.Text);
MessageBox.Show("Xóa thành công", "Thông báo");
Show_GridView();
}
Bước 12: Lập trình sự kiện SelectionChanged của lưới
private void dg_Hienthi_SelectionChanged(object sender, EventArgs e)
{
if( dg_Hienthi.SelectedRows.Count > 0)
{
txtSoPX.Text = dg_Hienthi.CurrentRow.Cells[0].Value.ToString();

94
Tập bài giảng Lập trình cơ sở dữ liệu

cbmakh.Text = dg_Hienthi.CurrentRow.Cells[2].Value.ToString();
dtpNgayX.Value =
DateTime.Parse(dg_Hienthi.CurrentRow.Cells[1].Value.ToString());
}
}
Bước 13: Lập trình sự kiện Click của nút tìm kiếm
private void btnTimkiem_Click(object sender, EventArgs e)
{
var PX = qlkdDB.sp_SearchtbPX(txtSoPX.Text);
dg_Hienthi.DataSource = PX.ToList();
}
Bước 14: Lập trình sự kiện SelectedIndexChanged của combox
private void cbmakh_SelectedIndexChanged(object sender, EventArgs e)
{
txtTenkh.Text = qlkdDB.sp_SearchtbKhach(cbmakh.Text).First().Tenkh;
}

95
Tập bài giảng Lập trình cơ sở dữ liệu

CHƯƠNG 4: THIẾT KẾ BÁO CÁO BẰNG CRYSTAL REPORT


4.1. Giới thiệu Crystal Report
Crystal Reports (CR) là một trong những phần mềm hàng đầu để tạo ra các report
tương tác, được tích hợp rộng rãi vào ứng dụng Windows và Web. CR đã được sử dụng
trong Visual Studio (VS) từ 1993 nhưng với sự ra mắt của VS.Net 2002 thì phiên bản
mới CR.NET ra đời và được tích hợp vào VS.Net. Nhưng từ VS.Net 2010 trở đi CR.NET
lại không được tích hợp. Do đó, cần cài đặt CR.NET.
Download bộ cài tại địa chỉ: http://scn.sap.com/docs/DOC-7824 . Lựa chọn phiên
bản phù hợp, download và tiến hành cài đặt.
4.2. Thiết kế Report bằng công cụ Wizard
Bước 1: Chọn chuột phải tên dự án trong Solution Explorer/Chọn Add/Chọn New
Item
Bước 2: Chọn loại Report
+ Chọn Reporting
+ Chọn Crystal Report
+ Nhập tên cho Crystal Report tại mục Name
+ Chọn Add

Hình 4.1. Nhập tên cho Report.


Bước 3: Chọn Using the Report Wizard/Chọn Standard/Chọn OK

Hình 4.2. Tạo Report bằng công cụ Wizard


Bước 3: Chọn loại kết nối đến dữ liệu nguồn
96
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.3. Chọn loại kết nối đến dữ liệu nguồn


Bước 4: Chọn Provider

Hình 4.4. Chọn Provider


Bước 5: Cung cấp thông tin để đăng nhập vào cơ sở dữ liệu nguồn
- Nhập tên của Server tại mục Server
- Nhập tên của cơ sở dữ liệu chứa dữ liệu nguồn tại mục Database:
- Trường hợp 1: Đăng nhập bằng tài khoản của SQL Server thì nhập
+ User ID: Tên của người dùng
+ Password: Mật khẩu của người dùng
- Trường hợp 2: Đăng nhập bằng tài khoản của Window thì chọn Integrated Security.
- Chọn Next/Finish

97
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.5. Cung cấp thông tin để đăng nhập vào cơ sở dữ liệu nguồn
Bước 6: Chọn dữ liệu nguồn (Table/View/Storted Procedure)/Chọn Next

Hình 4.6. Chọn dữ liệu nguồn


Bước 7: Chọn các trường cần hiện thị trên Report/Chọn Next

Hình 4.7. Chọn các trường cần hiện thị trên Report
Bước 8: Chọn trường để nhóm/Chọn Next

98
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.8. Chọn trường để nhóm


Bước 9: Chọn trường để tính toán/Chọn phép toán/Chọn Next

Hình 4.9. Chọn trường để tính toán


Bước 10: Chọn trường để sắp xếp theo nhóm/Chọn Next

Hình 4.10. Chọn trường để sắp xếp theo nhóm


Bước 11: Chọn loại đồ thị để hiện thị dữ liệu/Chọn Next

99
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.11. Loại đồ thị hiện thị trên Report


Bước 12: Lọc dữ liệu hiện thị trên Report
- Chọn trường
- Chọn phép toán
- Nhập giá trị
- Chọn Next

Hình 4.12. Lọc dữ liệu hiện thị trên Report


Bước 13: Chọn định dạng của Report/Chọn Finish

100
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.13. Chọn định dạng của Report


Kết quả của Report được thiết kế bằng công cụ Wizard

Hình 4.14. Kết quả tạo Report bằng công cụ Wizard.


Chọn tab Main Report Preview để xem hiển thị dữ liệu từ cơ sở dữ liệu.

101
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.15. Chọn chế độ Main Report Preview.


4.3. Thiết kế Report bằng công cụ Designer
4.3.1. Tạo mới file Report
Bước 1: Chọn chuột phải tên dự án trong Solution Explorer/Chọn Add/Chọn New
Item
Bước 2: Chọn Reporting/Chọn Crystal Report/ Nhập tên cho Crystal Report tại mục
Name/Chọn Add
Bước 3: Chọn As a Blank Report/Chọn OK

Hình 4.16. Report trắng


Các Section:
- Report Header: Dùng để tạo tiêu đề cho mỗi report. Tiêu đề này chỉ in một lần ở
đầu mỗi report.

102
Tập bài giảng Lập trình cơ sở dữ liệu

- Page Header: Dùng để tạo tiêu đề đầu trang trên mỗi report. Tiêu đề này in ở đầu
mỗi trang in.
- Details: Dùng để thiết kế phần chi tiết cho mỗi dòng in (ứng với từng record trên
bảng dữ liệu).
- Page Footer: Dùng để tạo tiêu đề cuối trang trên mỗi report. Tiêu đề này in ở cuối
mỗi trang in.
- Report Footer: Dùng để tạo tiêu đề cuối cho mỗi report. Tiêu đề này chỉ in một lần
ở cuối mỗi report.
4.3.2. Đưa các đối tượng vào Report

Hình 4.17. Toolbox để thiết kế các đối tượng trên Report


1) Đưa đối tượng Text Object vào Report
Trên thanh công cụ Toolbox, chọn Text Object/Kéo thả vào Report/Nhập thông
tin
2) Đưa đối tượng Line Object vào Report
Trên thanh công cụ Toolbox, chọn Line Object/Kéo thả vào Report
3) Đưa đối tượng Box Object vào Report
Trên thanh công cụ Toolbox, chọn Box Object/Kéo thả vào Report
4.3.3. Chọn dữ liệu nguồn cho Report
Bước 1: Trên Field Exporer, chọn chuột phải Database Fields/Chọn DataExpert

Hình 4.18. Kết nối đến dữ liệu nguồn


Bước 2: Chọn dữ liệu nguồn/Chọn OK

103
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.19. Chọn dữ liệu nguồn


Kết quả dữ liệu nguồn đã được đưa vào thanh công cụ Field Explorer

Hình 4.20. Kết quả dữ liệu nguồn trên thanh công cụ Field Explorer
4.3.4. Đưa các trường vào Report
Chọn tên trường trong Database Fields/Kéo thả vào vùng thích hợp trên Report
4.3.5. Làm việc với nhóm (Group)
Khi muốn nhóm các thông tin trên Report ta cần phải tạo ra một Group trên Report.
Chẳng hạn, nhóm thông tin mặt hàng theo số phiếu xuất.
1) Thêm mới một nhóm
Bước 1: Trên Main Report, chọn chuột phải/Chọn Insert/Chọn Group

104
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.21. Thêm một nhóm mới vào Report


Bước 2: Chọn tên trường làm tiêu chí nhóm/Chọn chiều sắp xếp/Chọn OK

Hình 4.22. Chọn trường làm tiêu chí nhóm


2) Chỉnh sửa nhóm
Bước 1: Trên Main Report, chọn chuột phải vào Group Header hoặc Group
Footer/Chọn Group Expert

Hình 4.23. Chọn chế độ chỉnh sửa nhóm


Bước 2: Thay đổi tiêu chí/Chọn OK

105
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.24. Chọn chế độ chỉnh sửa nhóm


4.3.6. Sắp xếp thông tin (Record Sort)
Bước 1: Trên Main Report, chọn chuột phải /Chọn Report/Chọn Record Sort Expert.
Bước 2: Chọn trường làm tiêu chí sắp xếp/Chọn chiều sắp xếp/Chọn OK

Hình 4.25. Chọn trường làm tiêu chí sắp xếp


4.3.7. Làm việc với trường tổng hợp (Summary)
Khi muốn đưa vào Report các trường được tạo ra từ các trường (sum, average,
minimum, maximum, ...) cần tạo ra một Summary hoặc Running Total Fields. Chẳng
hạn, tổng thành tiền.
Cách 1: Dùng công cụ Summary
1) Thêm một trường tổng hợp
Bước 1: Trên Main Report, chọn chuột phải /Chọn Insert/Chọn Summary.
Bước 2: Thiết lập các thông số cho trường tổng hợp
- Chọn trường để xây dựng trường tổng hợp tại mục Choose the field to summarize
- Chọn phép toán tại mục Calculate this summary
- Chọn vị trí để trường tính tổng hợp (Mức group hoặc report) tại mục Summary
location
- Chọn OK

106
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.26. Thiết lập các thông số cho trường tổng hợp (Summary)
2) Thay đổi trường tổng hợp
Bước 1: Trên Main Report, chọn chuột phải vào trường tổng hợp/Chọn Change
summary operation.
Bước 2: Thiết lập lại các thông số/Chọn OK

Hình 4.27. Thiết lập lại các thông số cho trường tổng hợp (Summary)
Cách 2: Dùng công cụ Running Total View
1) Thêm một trường tổng hợp
Bước 1: Trên Field Explorer, chọn chuột phải Running Total Fields/Chọn New.
Bước 2: Thiết lập các thông số cho trường tổng hợp
- Nhập tên cho trường tổng hợp tại mục Running Total Name
- Chọn trường để xây dựng trường tổng hợp tại mục Field to summarize
- Chọn phép toán tại mục Type of summary
- Chọn vị trí để trường tính tổng hợp tại mục Evaluate:
+ For each record: Thay đổi theo bản ghi
+ On change of field: Thay đổi ở mỗi trường
+ On change of group: Thay đổi ở mỗi nhóm
- Chọn mức thiết lập lại công thức tổng hợp
+ On change of field: Thay đổi ở mỗi trường
+ On change of group: Thay đổi ở mỗi nhóm
- Chọn OK

Hình 4.28. Thiết lập các thông số cho trường tổng hợp (Total Fields)
Bước 3: Đưa Running Total Fields vào Report bằng cách chọn tên Running Total
Fields trong Field Explorer/Kéo thả vào Report.

107
Tập bài giảng Lập trình cơ sở dữ liệu

4.3.8. Làm việc với Fomular Fields


Khi muốn đưa vào Report các trường được tạo ra từ các trường khác ta cần tạo ra
một Fomular Fields. Chẳng hạn, trường thành tiền (Đơn giá * Số lượng).
Bước 1: Trên Field Explorer, chọn chuột phải Fomular Fields/Chọn New.
Bước 2: Nhập tên cho Fomular Fields/Chọn OK

Hình 4.29. Nhập tên cho Fomular Fields


Bước 3: Xây dựng công thức cho Fomular Fields/Chọn Save/OK

Hình 4.30. Xây dựng công thức Fomular Fields


Bước 4: Đưa Fomular Fields vào Report bằng cách chọn tên Fomular Fields trong
Field Explorer/Kéo thả vào Report.
4.3.9. Đưa các trường có sẵn vào Report
Khi muốn đưa vào Report các trường đặc biệt, ta sử dụng công cụ Special Fields.

108
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.31. Các trường có sẵn


Đưa Special Fields vào Report bằng cách chọn tên Special Fields trong Field
Explorer/Kéo thả vào Report.
4.3. Xem Report
Để xem report, chọn vào mục Main Report Preview.
4.5. Tích hợp Report vào ứng dụng
4.5.1. Tạo môi trường tích hợp
Để sử dụng được Report cần phải xây dựng môi trường phát triển. Có hai môi trường
phát triển: Môi trường Windows và Web. Report sẽ được tích hợp trên WinForm hoặc
WebForm.
Trên WinForm sẽ chứa các Control làm điều kiện để thực hiện in Report.
4.5.2. Tích hợp report vào Form
Bước 1: Trên Toolbox/Chọn Reporting/Chọn CrytalReportViewer/Kéo thả vào
form/Đặt tên cho CrytalReportViewer tại thuộc tính Name.

109
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.32. Đưa CrytalReportViewer vào form


Bước 2: Trên CrytalReportViewer, chọn Choose Crystal Report/Chọn Crystal
Report đã thiết kế/Chọn OK.

Hình 4.33. Chọn Crytal Report để tích hợp vào form


Report sau khi được tích hợp vào Form.

Hình 4.34. Kết quả Crytal Report được tích hợp vào Form
4.5.3. Lập trình tích hợp Report vào Form
1) Khai báo đối tượng Crystal Report
<Crystal_Report_Name> <CReport_Object_Name> = new
<Crystal_Report_Name>();
Trong đó:
- CReport_Object_Name: Tên của đối tượng Crystal_Report
- Crystal_Report_Name: Tên Crystal_Report đã được thiết kế
2) Truyền dữ liệu cho đối tượng Crystal Report
- Khai báo thực thể lớp cần tìm kiếm
<Entity_Class_Name> <Entity_Name> = new <Entity_Class_Name>();
- Tạo truy vấn tìm kiếm
var <Query_Name> = from <Element_Name> in
<DBContext_Name>.<Entity_Class_Name>s
[where <Element_Name>.<Property_Name> = <Value>] select <Element_Name>;
- Thiết lập nguồn dữ liệu cho đối tượng Crystal Report
<CReport_Object_Name>.SetDataSource(<Query_Name>.ToList());
Trong đó:
- Entity_Class_Name: là tên tập thực thể chứa dữ liệu nguồn sẽ hiện thị trên
Report
- Condition_Expression: Là biểu thức điều kiện
3) Tích hợp Report vào Form
<CrytalReportViewer_Name>.ReportSource= <CReport_Object_Name>

110
Tập bài giảng Lập trình cơ sở dữ liệu

Trong đó: CrytalReportViewer_Name là tên của Crytal Report Viewer trên form
Ví dụ:
//Khai báo CrystalReport rp_PXH
rp_PXH rp = new rp_PXH();
var rpxQuery = from px in qlkdDB.View_TKPX
where px.SoPX == cb_soPX.Text
select px;
//Thiết lập nguồn dữ liệu cho report
rp.SetDataSource(rpxQuery.ToList());
crv_px.ReportSource = rp;
4.6. Ví dụ
Ví dụ 4.1:
1) Thiết kế Report in phiếu xuất hàng theo mẫu:

Hình 4.35. Mẫu phiếu xuất hàng


2) Thiết kế Form theo mẫu, tích hợp Report vào Form và lập trình nút lệnh in ấn

111
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.36. Form in phiếu xuất hàng


Hướng dẫn:
1) Thiết kế Report in phiếu xuất hàng
Bước 1: Tạo View có tên là View_TKPX chứa thông tin của phiếu xuất hàng

Hình 4.37. View chứa thông tin của phiếu xuất hàng
Bước 2: Tạo mới file Report, đặt tên là rp_PXH.rpt
Bước 3: Chọn dữ liệu nguồn cho Report (View_TKPX )
Bước 4: Tạo một nhóm mới theo số phiếu xuất
Bước 5: Đưa các đối tượng vào Report:
- Đối tượng Text Object: PHIẾU XUẤT HÀNG, Ngày, tháng, năm, Số, Đơn vị, Bộ
phận, Mẫu số 02 VT, Mã khách hàng, Tên khách hàng, Địa chỉ, STT, Mã hàng, Tên
hàng, Đơn vị tính, Số lượng , Đơn giá, Thành tiền, Danh sách mặt hàng, Tổng tiền,
112
Tập bài giảng Lập trình cơ sở dữ liệu

Người lập, Người nhận, Kế toán trưởng, Giám đốc, (Ký, ghi rõ họ tên), Tổng tiền (bằng
chữ):
- Đối tượng Box Object
- Đối tượng Line Object
Bước 5: Tạo các Fomular Fields

- Công thức lấy ra ngày xuất hàng: Day ({View_TKPX.NgayX})


- Công thức lấy ra tháng xuất hàng: Month ({View_TKPX.NgayX})
- Công thức lấy ra năm xuất hàng: Year ({View_TKPX.NgayX})
- Công thức tính thành tiền: {View_TKPX.DGX}*{View_TKPX.SLX}
Bước 6: Tạo các Running Total Field

Hình 4.38. Tạo trường tính tổng tiền

Hình 4.39. Tạo trường số thứ tự


Bước 7: Đưa các trường vào vị trí thích hợp trên Report

113
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.40. Main Report của rp_PXH


2) Thiết kế Form theo mẫu, tích hợp Report vào Form và lập trình nút lệnh in ấn
Bước 1: Tạo và thiết kế Form in phiếu xuất hàng
STT Đối tượng Thuộc tính Giá trị
Name frm_InPX
1 Form
Text In phiếu xuất hàng
2 GroupBox Text Thông tin phiếu xuất hàng
3 Label Text Ngày xuất
4 Label Text Số phiếu
5 ComboBox Name cb_soPX
6 DateTimePicker Name dtp_ngayx
7 CrystalReportViewer Name crv_px
Name btnIn
8 Button
Image System.Drawing.Bitmap
Bước 2: Thêm View View_TKPX vào trong mô hình EDM QLKD.edmx và thực
hiện thiết lập giá trị NulLabel của các thuộc tính là False.

114
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 4.41. Thực thể View_TKPX.

Hình 4.42. Thiết lập giá trị NulLabel cho thuộc tính Tenkh của View_TKPX.
Bước 3: Khai báo không gian tên System.Data.Entity để sử dụng lớp DbFunctions
using System.Data.Entity;
Bước 4: Khai báo đối tượng
QLKDEntities qlkdDB = new QLKDEntities();
Bước 5: Lập trình sự kiện Click của nút btnIn
private void btnIn_Click(object sender, EventArgs e)
{
//Khai báo CrystalReport rp_PXH
rp_PXH rp = new rp_PXH();
var rpxQuery = from px in qlkdDB.View_TKPX
where px.SoPX == cb_soPX.Text
select px;
//Thiết lập nguồn dữ liệu cho report
rp.SetDataSource(rpxQuery.ToList());
crv_px.ReportSource = rp;

115
Tập bài giảng Lập trình cơ sở dữ liệu

}
Bước 6: Lập trình sự kiện ValueChanged của DateTimePicker dtp_ngayx. Trong sự
kiện sử dụng hàm DbFunctions.TruncateTime(<DateTime_Name>) để trả về ngày của
một đối tượng lớp DateTime.
private void dtp_ngayx_ValueChanged(object sender, EventArgs e)
{
cb_soPX.DataSource = null;
var pxQuery = from px in qlkdDB.tbPXes
where DbFunctions.TruncateTime(px.NgayX) ==
DbFunctions.TruncateTime(dtp_ngayx.Value) select px;
cb_soPX.Items.Clear();
cb_soPX.DataSource = pxQuery.ToList();
cb_soPX.DisplayMember = "sopx";
}

116
Tập bài giảng Lập trình cơ sở dữ liệu

CHƯƠNG 5: PHÂN PHỐI VÀ ĐÓNG GÓI ỨNG DỤNG


5.1. Lập kế hoạch triển khai đóng gói dự án
Cài đặt theo mô hình COM trước kia có rất nhiều hạn chế như: các đăng ký DLL bị
trùng lặp, không phù hợp phiên bản, xung đột. Một số chương trình cài đặt được nhưng
không thực thi được, cài đặt xong không gỡ được hay gỡ nhưng vẫn để lại rác…Giờ đây
C Sharp đã khắc phục những nhược điểm đó vì nó có thể cài đặt mà không cần đăng ký
vào Registry của hệ thống. Nó chủ yếu dựa trên bộ khung .NET Framework thay vì yêu
cầu đối tượng COM gọi đến hàm API của Windows. Chương trình sẽ được biên dịch
thành các gói (Assembly) và chương trình cài đặt sẽ ráp các phần lại cùng với các file
thư viện cần thiết.
Một gói Assembly của ứng dụng .NET gồm 4 thành phần: ngôn ngữ diễn dịch trung
gian MSIL (Microsoft Intermediate Language), mã (MSIL code), dữ liệu mô tả
(metadata) và file chứa thông tin (manisfest file), các file hỗ trợ (support files) và tài
nguyên (resource) dành cho chương trình.
Để đóng gói một dự án, cần tạo Form chủ để liên kết tất cả các form xử lý nghiệp vụ
sao cho thuận tiện nhất đối với người sử dụng.
5.1.1. Thiết kế Form chủ
Bước 1: Tại Solution Explorer, chọn chuột phải tên dự án/Chọn Add/ Chọn New
Item
Bước 2: Chọn MDI Parent Form/Nhập tên form cha tại mục Name/Chọn OK.

Hình 5.1. Tạo Form chủ


Bước 3: Thiết kế Form chủ

117
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.2. Ví dụ Form chủ của dự án quản lý kinh doanh


5.1.2. Liên kết các Form lên Form chủ
Khai báo tại sự kiện click của ToolStripMenuItem
<Form_Name> <Form_Object_Name> = new <Form_Name>();
<Form_Object_Name>.MdiParent = this;
<Form_Object_Name>.Show();
Ví dụ: Khai báo tại sự kiện Click của InPhiếuXuấtToolStripMenuItem
private void InPhiếuXuấtToolStripMenuItem_Click(object sender, EventArgs
e)
{
frmInPX f1 = new frmInPX();
f1.MdiParent = this;
f1.Show();
}

Hình 5.3. Liên kết form in phiếu xuất hàng vào form chủ
5.2. Các cách đóng gói và triển khai ứng dụng khác nhau
Khi bắt đầu chuẩn bị cho việc phân phối sản phẩm của mình, hãy xem xét các phương
thức cài đặt khác nhau:
Cài đặt ứng dụng lên máy tính và đăng ký nó với Windows Registry
Tạo chương trình cài đặt cho phép chương trình có thể cài từ mạng LAN hay Internet
Đóng gói ứng dụng cho phép cài từ CD
Đóng gói ứng dụng thành các file .CAB (một dạng file tự bung) có thể dùng cho các
trình duyệt download về hay sao chép đi cài ở bất kỳ đâu.

118
Tập bài giảng Lập trình cơ sở dữ liệu

Trong Visual Studio có thể nhanh chóng tạo ra dự án đóng gói Deployment bằng trình
Setup Winzard. Việc tùy biến dự án là hoàn toàn dễ dàng bằng cách thay đổi các tùy
chọn. Nếu muốn đóng gói lên CD thì cần có đầu ghi CD.
Trên mỗi máy chạy chương trình .NET cần có một bộ khung .NET FrameWork. Sau
này trong các phiên bản hệ điều hành sẽ chứa sẵn .NET Framework Runtime. Nếu máy
đã có sẵn thì việc cài đặt chỉ đơn giản là sao chép và chạy.
Tuy nhiên hầu như khi đóng gói Visual Studio đã nhúng luôn thư viện .NET runtime
kèm theo chương trình nên nếu dung lượng bộ cài có lớn hơn nhiều so với chương trình.
5.3. Tạo dự án Deployment
Bước 1: Chọn chuột phải vào Solution/Chọn Add/Chọn New Project
Bước 2: Chọn Other Project Types/Chọn Setup and Deployment/Chọn Visual Studio
Installer/Chọn Setup Project/Nhập tên cho Setup Project/Chọn vị trí lưu file/Chọn OK.

Hình 5.4. Tạo dự án Deployment


5.4. Tùy biến các lựa chọn đóng gói
5.4.1. Cấu hình các thiết lập
1) Thêm file *.exe
Bước 1: Chọn chuột phải vào Application Folder/Chọn Add/Chọn File

119
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.5. Thêm file *.exe


Bước 2: Chọn file *.exe trong thư mục Debug của dự án/Chọn Open

Hình 5.6. Chọn file *.exe


2) Thêm Project Output
Bước 1: Chọn chuột phải vào Application Folder/Chọn Add/Chọn Project Output
Bước 2: Chọn OK

120
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.7. Thêm Project Output


3) Thêm Ico
Bước 1: Chọn chuột phải vào Application Folder/Chọn Add/Chọn File
Bước 2: Chọn file ico/Chọn Open

Hình 5.8. Chọn file ico


File System sau khi thiết lập:

121
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.9. File System sau khi thiết lập


5.4.2. Tạo shortcut cho ứng dụng cài đặt
Bước 1: Chọn User’s Desktop/Chọn chuột phải/Chọn Create New Shortcut

Hình 5.10. Tạo Shortcut cho ứng dụng


Bước 2: Chọn Application Folder/Chọn file *.exe/Chọn OK

Hình 5.11. Chọn file cần tạo Shortcut


Bước 3: Nhập tên cho file Shortcut

122
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.12. Nhập tên cho file Shortcut


Bước 4: Chọn biểu tượng cho file Shortcut
- Chọn chuột file Shortcut/Chọn Properties/Chọn thuộc tính Icon/Chọn Browse
- Chọn file Ico trong Application Folder/Chọn OK

Hình 5.13. Chọn biểu tượng cho file Shortcut


5.4.3. Thiết lập các thuộc tính chương trình
Bước 1. Chọn tên dự án setup từ cửa sổ Solution Explorer/Mở cửa sổ Properies
Bước 2: Thiết lập các thuộc tính
- Author: Dùng đặt tên cho tác giả hay nhà sản xuất. Tên này cũng được dùng làm
thư mục cho chương trình đặt trong Program Files. Khi chương trình Setup thực thi,
thông tin về tác giả sẽ được đặt trong trường Contact của hộp thoại Support Info, hộp
thoại này bạn có thể truy xuất sau đó thông qua mục Add/Remove Programs trong
Control Panel.
- Title: Chứa tên chương trình Setup
- Version: Chứa số hiệu phiên bản cho chương trình

123
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.14. Thiết lập tên công ty và phiên bản chương trình
Bước 3. Xem lại các thuộc tính khác nữa trước khi đóng gói thực sự.
5.4.4. Đặt các thuộc tính cho gói ứng dụng
Bước 1: Chọn tên dự án setup từ cửa sổ Solution Explorer/ Chọn Properies

124
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.15. Đặt các thuộc tính cho gói ứng dụng
Bước 2: Thay đổi các thông số
- Output File name: Cho phép đặt tên cho file cài đặt.
- Chọn dạng gói tại Package files:
+ As Loose Uncompress Files: Tạo ra các file không nén trong cùng thư mục với file
.msi
+ In Setup File: Tạo ra một file cài đặt đơn chứa tất cả các file yêu cầu của chương
trình
+ In Cabinet Files: Tạo ra một hay nhiều file .CAB là các file chứa ứng dụng của
bạn trong đó.
Bước 3: Chọn OK.
5.5. Biên dịch, đóng gói dự án và kiểm tra việc tạo file cài đặt
Trong Solution Explorer/Chọn dự án Setup/Chọn chuột phải/Chọn Rebuild

Hình 5.16. Biên dịch và đóng gói dự án


Nếu biên dịch thành công thì một thông báo hiện ở cuối góc trái màn hình
.
Kết quả sau file Setup sau khi biên dịch

125
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.17. Kết quả sau file Setup sau khi biên dịch
5.6. Cài đặt, tìm hiểu các file Setup và gỡ chương trình
5.6.1. Cài đặt chương trình
Bước 1: Chạy file Setup_PMQLKD.exe để khởi động chương trình cài đặt/Chọn
Next

Hình 5.18. Màn hình chào mừng cài đặt chương trình
Bước 2: Nhập thông tin về thư mục cài đặt và các tùy chọn bổ sung/Chọn Next

Hình 5.19. Hộp thoại Select Installation Folder


Bước 3: Chọn Next

126
Tập bài giảng Lập trình cơ sở dữ liệu

Hình 5.20. Hộp thoại bắt đầu cài đặt.

Hình 5.21. Tiến trình cài đặt.


Bước 4: Chọn Close

Hình 5.22. Tiến trình cài đặt kết thúc.


Sau khi cài đặt thành công, trên màn hình Desktop có biểu tượng:
127
Tập bài giảng Lập trình cơ sở dữ liệu

5.6.2. Tháo gỡ chương trình


Việc tháo gỡ chương trình được thực hiện như mọi chương trình khác.

Hình 5.23. Tháo gỡ chương trình

128
Tập bài giảng Lập trình cơ sở dữ liệu

BÀI TẬP
Câu 1: Cho CSDL quản lý tuyển sinh (QLTS) gồm các bảng sau:
TS(SBD, Hoten, NS, GT, QQ, DT, DL, DH, SP): Chứa thông tin về các thí sinh
UT(MaUT, TenUT, DC): Chứa thông tin về các loại ưu tiên.
NH(MaN, TenN, SoCT): Chứa thông tin về ngành học.
Trong đó: SBD-Số báo danh, Hoten-Họ tên, NS-Ngày tháng năm sinh, GT-Giới tính,
QQ-Quê quán, DT-Điểm toán, DL-Điểm lý, DH-Điểm hoá, SP-Số phòng dự thi, MaUT-
Mã loại ưu tiên, TenUT-Tên loại ưu tiên, DC-Điểm cộng, MaN-Mã ngành, TenN-Tên
ngành, SoCT-Số chỉ tiêu sẽ lấy vào ngành.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLTS và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLTS
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý kết quả thi

Yêu cầ u:
- Khi Form load: Danh mục các phòng được đưa vào Combo “Số phòng”, nút “Lưu”
không có hiệu lực, DataGridview không có hiệu lực.
- Khi người dùng một phòng thì danh sách các thí sinh của phòng đó sẽ hiện lên
DataGridview gồm các thông tin: Số báo danh, họ tên, ngày sinh, giới tính, quê quán.
- Nút “Nhập mới”: Khi người dùng chọn nút “Nhập mới” thì thông tin các cột điểm
toán, điểm lý, điểm hóa có hiệu lực, nút “Lưu” có hiệu lực; nút “Nhập mới” mất hiệu
lực.
- Nút “Hiệu chỉnh”: Khi người dùng chọn nút “Hiệu chỉnh” thì các cột điểm toán,
điểm lý, điểm hóa có hiệu lực, nút “Lưu” có hiệu lực, nút “Nhập mới” mất hiệu lực.
- Nút “Lưu”:
+ Sau khi người dùng nhâ ̣p các điểm cho các sinh viên, chọn nút “Lưu” thì thông tin
điểm toán, điểm lý, điểm hóa được lưu vào bảng TS trong cơ sở dữ liê ̣u; đồ ng thời cập
nhật thông tin vừa nhâ ̣p lên DataGridview, nút “Nhập mới” có hiệu lực.

129
Tập bài giảng Lập trình cơ sở dữ liệu

+ Sau khi người dùng sửa la ̣i điểm của các sinh viên, chọn nút “Lưu” thì lưu điểm thi
được sửa vào bảng TS trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông tin lên
DataGridview, nút “Hiệu chỉnh” hiệu lực.
b) Quản lý học phần

Yêu cầ u:
- Khi Form load: Thông tin trong bảng UT đươ ̣c hiể n thị trong DataGridview
- Nút “Về đầu”: Di chuyển con trỏ về dòng đầu tiên trên DataGridview
- Nút “Về cuối”: Di chuyển con trỏ về dòng cuối cùng trên DataGridview
- Nút “Tiếp”: Di chuyển con trỏ về dòng tiếp theo trên DataGridview
- Nút “Trước”: Di chuyển con trỏ về dòng trước trên DataGridview
- Nút “Thêm”: Khi người dùng chọn nút “Thêm” thì nút “Thêm” trở thành nút “Lưu”,
nút “Sửa” trở thành nút “Hủy”, thêm dòng trống vào DataGridView:
+ Sau khi người dùng nhâ ̣p các thông tin về ưu tiên, chọn nút “Lưu” thì mã ưu tiên,
tên ưu tiên, điểm cộng sẽ được lưu được bảng UT trong cơ sở dữ liê ̣u; đồ ng thời cập
nhật thông tin vừa nhập lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút “Hủy”
trở thành nút “Sửa”.
+ Sau khi người dùng sửa la ̣i các thông tin trên DataGridview, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng UT trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông
tin lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút “Hủy” trở thành nút “Sửa”.
- Nút “Sửa”: Khi kích cho ̣n một dòng trên DataGridview, chọn nút “Sửa” thì nút
“Thêm” trở thành nút “Lưu”, nút “Sửa” trở thành nút Hủy.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mô ̣ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nế u người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
c) Quản lý điểm

130
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầ u:
- Khi Form load: Thông tin trong bảng NH đươ ̣c hiể n thị trong DataGridview “Danh
sách ngành học”, nút “Lưu” không có hiệu lực.
- Nút “Nhâ ̣p mới”: Khi người dùng chọn nút “Nhập mới” thì thông tin trên các Control
sẽ được xóa, nút “Lưu” có hiệu lực, nút “Nhập mới” mất hiệu lực.
- Nút “Hiệu chỉnh”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách ngành
học” thì thông tin của dòng đó được hiể n thi ̣ lên các Control trong phần “Thông tin
ngành học”. Khi người dùng chọn nút “Hiệu chỉnh” và nhập đầy đủ các thông tin thì nút
“Lưu” có hiệu lực, nút “Hiệu chỉnh” mất hiệu lực.
- Nút “Lưu”:
+ Sau khi người dùng nhâ ̣p các thông tin trên các Control, chọn nút “Lưu” thì mã
ngành học, tên ngành học, chỉ tiêu tuyển sinh vào bảng NH trong cơ sở dữ liê ̣u; đồng
thời cập nhật thông tin vừa nhâ ̣p lên DataGridview, nút “Nhập mới” có hiệu lực.
+ Sau khi người dùng sửa la ̣i các thông tin trên các Control, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng NH trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông
tin lên DataGridview, nút “Hiệu chỉnh” hiệu lực.
- Nút “Xóa”: Khi kích cho ̣n một dòng trên DataGridview “Danh sách ngành học” thì
thông tin của dòng đó được hiể n thi lên
̣ các Control trong phần “Thông tin ngành học”.
Khi người dùng chọn nút “Xóa” thì hiể n thi một
̣ hô ̣p thoa ̣i hỏi người dùng có chắ c chắ n
muố n xóa không; nếu người dùng nhấ n nút Yes thì cho xóa dòng tương ứng ở bảng SV
trong cơ sở dữ liê ̣u, đồ ng thời cũng xóa dòng đó trên DataGridview.
- Nút “Tìm kiếm”: Khi người dùng nhập mã ngành học cần và chọn nút “Tìm kiếm”
thì kết quả tìm kiếm sẽ hiện thị trên DataGridview.
d) Tra cứu điểm theo sinh viên và học phần

131
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầ u:
- Khi Form load: Nút “Tìm kiếm” không có hiệu lực.
- Khi người dùng nhập số báo danh và chọn nút “Tìm kiếm” thì thông tin gồm: Số
báo danh, họ tên, ngày sinh, tên ngành, điểm toán, điểm lý, điểm hóa, điểm cộng,
tổng điểm tương ứng với số báo danh được nhập sẽ hiện lên trên DataGridview.
- Khi người dùng nhập họ tên và chọn nút “Tìm kiếm” thì thông tin gồm: Số báo
danh, họ tên, ngày sinh, tên ngành, điểm toán, điểm lý, điểm hóa, điểm cộng, tổng
điểm tương ứng với họ tên được nhập sẽ hiện lên trên DataGridview.
Câu 2: Cho CSDL quản lý giáo viên (QLGV) gồm các bảng sau:
COSO(Macoso, Tencoso): Lưu thông tin về các cơ sở đào tạo
DONVI(Madonvi, Tendonvi, Macoso): Lưu thông tin về các đơn vị
GV(Magv, Hoten, Sdt, Ghichu, Madonvi): Lưu thông tin về các giáo viên.
Trong đó: Macoso-Mã cơ sở, Tencoso-Tên cơ sở, Madonvi-Mã đơn vị, Tendonvi-
Tên đơn vị, Magv-Mã giáo viên, Hoten-Họ tên, Sdt-Số điện thoại, Ghichu-Ghi chú.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLGV và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLGV
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Hiện thị danh sách giáo viên

132
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầ u:
- Khi người dùng chọn một cơ sở thì chương trình hiển thị danh sách đơn vị đào tạo
thuộc cơ sở đó (sắp xếp theo tên đơn vị), chưa đơn vị nào được chọn từ ComboBox này,
và không có giáo viên nào hiển thị trong danh sách giáo viên.
- Người dùng chọn một đơn vị đào tạo thì danh sách giáo viên (thuộc đơn vị được
chọn) sẽ hiển thị trong danh sách giáo viên (thông tin hiển thị chỉ chứa tên giáo viên và
được đánh số thứ tự).
- Người dùng có thể bấm phải chuột trên một giáo viên từ danh sách để hiển thị popup
menu chứa 2 menu: Hiện thị thông tin chi tiết của GV, xóa GV đang chọn. Nếu người
dùng bấm phải chuột trên danh sách khi chưa chọn giáo viên nào thì hai menu này sẽ bị
mờ, không cho sử dụng.
- Khi người dùng chọn menu [Xóa GV đang chọn], chương trình sẽ xuất hiện hộp
thoại xác nhận:
+ Nếu người dùng đồng ý, chương trình sẽ xóa giáo viên này ra khỏi cơ sở dữ liệu và
cập nhật danh sách trên màn hình.
+ Nếu người dùng không đồng ý thì sẽ trở lại chương trình.

- Khi người dùng chọn menu [Hiển thị thông tin chi tiết GV] hoặc double click vào
một giáo viên trong danh sách, chương trình sẽ hiển thị frm_KQGV trên với thông tin
giáo viên đang chọn.
b) Thông tin chi tiết giáo viên

133
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầ u:
- Khi Form load: Hiện thị thông tin giáo viên được chọn từ form frm_KQGV
- Người dùng nhấn nút quay về để thoát khỏi form.
c) Quản lý đơn vị

Yêu cầ u:
- Khi Form load: Thông tin trong bảng DONVI đươ ̣c hiể n thị trong DataGridview
“Danh sách đơn vị”, Mã cơ sở từ bảng COSO được đưa vào Combox “Mã cơ sở”.
- Nút “Thêm”: Khi người dùng chọn nút “Thêm” thì nút “Thêm” trở thành nút “Lưu”,
nút “Sửa” trở thành nút “Hủy”:
+ Sau khi người dùng nhâ ̣p các thông tin trên các Control, chọn nút “Lưu” thì mã đơn
vị, tên đơn vị, mã cơ sở sẽ được lưu được bảng DONVI trong cơ sở dữ liê ̣u; đồng thời
cập nhật thông tin vừa nhập lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút
“Hủy” trở thành nút “Sửa”.
+ Sau khi người dùng sửa la ̣i các thông tin trên các Control, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng DONVI trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i
thông tin lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút “Hủy” trở thành nút
“Sửa”.

134
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Sửa”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách đơn vị” thì
thông tin của dòng đó được hiể n thị lên các textbox trong phần “Nhập thông tin đơn vị”.
Sau khi người dùng sửa la ̣i các thông tin trên các textbox, chọn nút “Sửa” thì nút “Thêm”
trở thành nút “Lưu”, nút “Sửa” trở thành nút Hủy:
- Nút “Xóa”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách đơn vị” thì
thông tin của dòng đó được hiể n thị lên các textbox trong phần “Nhập thông tin đơn vị”.
Khi người dùng chọn nút “Xóa” thì xóa dòng tương ứng ở bảng DONVI trong cơ sở dữ
liê ̣u, đồ ng thời cũng xóa dòng đó trên DataGridview.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mộ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nếu người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
Câu 3: Cho CSDL quản lý điểm (QLD) gồm các bảng sau:
SV(MaSV, Hoten, GT, NS, QQ, MaL): Chứa thông tin về các sinh viên.
HP(MaHP, TenHP, SoTC, HK): Chứa thông tin về các học phần.
Diem(MaSV, MaHP, Diem): Chứa thông tin về điểm của từng học phần của từng
sinh viên.
Trong đó: MaSV-Mã sinh viên, Hoten-Họ tên sinh viên, GT-Giới tính, NS-Ngày
sinh, QQ-Quê quán, MaHP-Mã học phần, TenHP-Tên học phần, SoTC-Số tín chỉ, HK-
Học kỳ, Diem-Điểm.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLD và các bảng dữ liệu với kiểu dữ liệu tự chọn phù
hợp.
2) Tạo dự án đặt tên là QLD
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý sinh viên

Yêu cầ u:

135
Tập bài giảng Lập trình cơ sở dữ liệu

- Khi Form load: Thông tin trong bảng SV đươ ̣c hiể n thi ̣trong DataGridview “Danh
sách sinh viên”, nút “Lưu” không có hiệu lực.
- Nút “Nhâ ̣p mới”: Khi người dùng chọn nút “Nhập mới” thì thông tin trên các Control
sẽ được xóa, nút “Lưu” có hiệu lực, nút “Nhập mới” mất hiệu lực.
- Nút “Hiệu chỉnh”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách sinh
viên” thì thông tin của dòng đó được hiể n thi lên
̣ các Control trong phần “Thông tin sinh
viên”. Khi người dùng chọn nút “Hiệu chỉnh” và nhập đầy đủ các thông tin thì nút “Lưu”
có hiệu lực, nút “Hiệu chỉnh” mất hiệu lực.
- Nút “Lưu”:
+ Sau khi người dùng nhâ ̣p các thông tin trên các Control, chọn nút “Lưu” thì mã sinh
viên, họ tên, giới tính, ngày sinh, quê quán, mã lớp bảng SV trong cơ sở dữ liê ̣u; đồng
thời cập nhật thông tin vừa nhâ ̣p lên DataGridview, nút “Nhập mới” có hiệu lực.
+ Sau khi người dùng sửa la ̣i các thông tin trên các Control, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng SV trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông
tin lên DataGridview, nút “Hiệu chỉnh” hiệu lực.
- Nút “Xóa”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách sinh viên” thì
thông tin của dòng đó được hiể n thi ̣ lên các Control trong phần “Thông tin sinh viên”.
Khi người dùng chọn nút “Xóa” thì hiể n thi ̣một hô ̣p thoa ̣i hỏi người dùng có chắ c chắ n
muố n xóa không; nế u người dùng nhấn nút Yes thì cho xóa dòng tương ứng ở bảng SV
trong cơ sở dữ liê ̣u, đồ ng thời cũng xóa dòng đó trên DataGridview.
- Nút “Tìm kiếm”: Khi người dùng nhập mã sinh viên cần và chọn nút “Tìm kiếm”
thì kết quả tìm kiếm sẽ hiện thị trên DataGridview.
b) Quản lý học phần

Yêu cầ u:
- Khi Form load: Thông tin trong bảng HP đươ ̣c hiể n thị trong DataGridview “Danh
sách học phần”.
- Nút “Thêm”: Khi người dùng chọn nút “Thêm” thì nút “Thêm” trở thành nút “Lưu”,
nút “Sửa” trở thành nút “Hủy”:
+ Sau khi người dùng nhâ ̣p các thông tin trên các Control, chọn nút “Lưu” thì mã học
phần, tên học phần, số tín chỉ, học kỳ sẽ được lưu được bảng HP trong cơ sở dữ liê ̣u;

136
Tập bài giảng Lập trình cơ sở dữ liệu

đồ ng thời cập nhật thông tin vừa nhâ ̣p lên DataGridview, nút “Lưu” trở thành nút
“Thêm”, nút “Hủy” trở thành nút “Sửa”.
+ Sau khi người dùng sửa la ̣i các thông tin trên các Control, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng SV trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông
tin lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút “Hủy” trở thành nút “Sửa”.
- Nút “Sửa”: Khi kích cho ̣n một dòng trên DataGridview “Danh sách học phần” thì
thông tin của dòng đó được hiể n thị lên các textbox trong phần “Nhập thông tin học
phần”. Sau khi người dùng sửa la ̣i các thông tin trên các textbox, chọn nút “Sửa” thì nút
“Thêm” trở thành nút “Lưu”, nút “Sửa” trở thành nút Hủy:
- Nút “Xóa”: Khi kić h cho ̣n một dòng trên DataGridview “Danh sách học phần” thì
thông tin của dòng đó được hiể n thi ̣ lên các textbox trong phần “Nhập thông tin học
phần”. Khi người dùng chọn nút “Xóa” thì xóa dòng tương ứng ở bảng HP trong cơ sở
dữ liê ̣u, đồ ng thời cũng xóa dòng đó trên DataGridview.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mộ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nếu người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
c) Quản lý điểm

Yêu cầ u:
- Khi Form load: Thông tin học kỳ được hiện lên trên Combobox “Học kỳ”,
DataGridview và nút “Lưu” không có hiệu lực.
- Khi người dùng chọn một học kỳ thì danh sách các học phần của học kỳ đó sẽ được
lọc ra và đưa lên Combobox “Học phần”.
- Nút “Tìm kiếm”: Khi người dùng chọn nút “Tìm kiếm” thì danh sách các sinh viên
học học phần thuộc học kỳ được chọn gồm: Số thứ tự, mã sinh viên, học tên, lớp, điểm
sẽ hiện lên trên DataGridview;
- Nút “Nhập mới”: Khi người dùng chọn nút “Nhập mới” thì cột điểm trong
DataGridview có hiệu lực, nút “Lưu” có hiệu lực.
- Nút “Lưu”:

137
Tập bài giảng Lập trình cơ sở dữ liệu

+ Sau khi người dùng nhập điểm học phần cho các sinh viên, chọn nút “Lưu” thì điểm
của học phần đã chọn của các sinh viên sẽ được lưu được bảng DIEM trong cơ sở dữ
liê ̣u; Đồ ng thời cập nhật la ̣i thông tin lên DataGridview, nút “Lưu” mất hiệu lực.
+ Sau khi người dùng sửa la ̣i cột điểm, chọn nút “Lưu” thì lưu các thông tin được sửa
vào bảng DIEM trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật la ̣i thông tin lên DataGridview,
nút “Lưu” mất hiệu lực.
- Nút “Hiệu chỉnh”: Khi người dùng chọn nút “Hiệu chỉnh” thì cột điểm trong
DataGridview có hiệu lực, nút “Lưu” có hiệu lực.
d) Tra cứu điểm theo sinh viên và kỳ

Yêu cầ u:
- Khi Form load: Mã sinh viên được hiện lên trên Combobox “Mã sinh viên”, tất các
Control còn lại trên form không có hiệu lực ngoại trừ nút “Kết thúc”.
- Khi người dùng chọn một sinh viên thì thông tin về tên sinh viên, ngày sinh, quê
quán tương ứng với mã sinh viên được chọn sẽ hiện lên trên các Textbox; Radio Button
“Lựa chọn” có hiệu lực.
- Khi người dùng chọn “Tất cả” và chọn nút “Tìm kiếm” thì thông tin gồm: Tên học
phần, điểm, học kỳ tương ứng với sinh viên được chọn sẽ hiện lên trên DataGridview.
- Khi người dùng chọn “một kỳ” thì Combo “Kỳ” có hiệu lực; Khi người dùng chọn
một kỳ và chọn nút “Tìm kiếm” thì thông tin gồm: Tên học phần, điểm, học kỳ tương
ứng với mã sinh viên của học kỳ được chọn sẽ hiện lên trên DataGridview.
- Nút “Kết thúc”: Khi người dùng chọn nút “Kết thúc” thì chương trình sẽ thoát khỏi
Form.
e) Tra cứu điểm theo sinh viên và học phần

138
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầ u:
- Khi Form load: Mã sinh viên được hiện lên trên Combobox “Mã sinh viên”, tất các
Control còn lại trên form không có hiệu lực ngoại trừ nút “Kết thúc”.
- Khi người dùng chọn một sinh viên thì thông tin về tên sinh viên, ngày sinh, quê
quán tương ứng với mã sinh viên được chọn sẽ hiện lên trên các Textbox; Radio Button
“Lựa chọn” có hiệu lực.
- Khi người dùng chọn “Tất cả” và chọn nút “Tìm kiếm” thì thông tin gồm: Tên học
phần, điểm, học kỳ tương ứng với sinh viên được chọn sẽ hiện lên trên DataGridview.
- Khi người dùng chọn “Một môn học” thì Combo “Tên môn học” có hiệu lực; Khi
người dùng chọn một học phần và chọn nút “Tìm kiếm” thì thông tin gồm: Tên học
phần, điểm, học kỳ tương ứng với mã sinh viên của học phần được chọn sẽ hiện lên trên
DataGridview.
- Nút “Kết thúc”: Khi người dùng chọn nút “Kết thúc” thì chương trình sẽ thoát khỏi
Form.
Câu 4: Cho CSDL quản lý thiết bị (QLTB) gồm các bảng sau:
- Bảng tblThietBi: Lưu thông tin về các thiết bị
Colunm Name Data Type Description Length Allow Null
MaTB Varchar Mã thiết bị, khóa chính 12 Not Null
TenTB Nvarchar Tên thiết bị 50
TinhTrang Nvarchar Tình trạng thiết bị 50
SoLuong Int Số lượng thiết bị 4
GhiChu Nvarchar Ghi chú 50
- Bảng tblPhieuNhap: Lưu thông tin về các phiếu nhập
Colunm Name Data Type Description Length Allow Null
MaPN Varchar Mã phiếu nhập, khóa chính 12 Not Null
MaNV Varchar Mã nhân viên, khóa ngoại 12
MaTB Varchar Mã thiết bị, khóa ngoại 12
NgayNhap dateTime Ngày nhập 8
SoLuong Int Số lượng nhập 4
TinhTrang Nvarchar Tình trạng 50

139
Tập bài giảng Lập trình cơ sở dữ liệu

- Bảng tblPhieuMuon: Lưu thông tin về các phiếu mượn


Colunm Name Data Type Description Length Allow Null
NVLapPhieu Varchar Mã nhân viên, khóa chính 12 Not null
MaTB varchar Mã thiết bị, khóa chính 12 Not null
TinhTrang Nvarchar Tình trạng 50
NgayMuon Datetime Ngày mượn 8
NVMuon Varchar Nhân viên mượn 12
SoLuong Int Số lượng mượn 4
MaPhong Varchar Mã phòng, khóa ngoại 12
- Bảng tblPhieuTra: Lưu thông tin về các phiếu trả
Colunm Name Data Type Description Length Allow Null
MaTB Varchar Mã thiết bị, khóa chính 12 Not Null
NVTra Varchar Nhân viên trả, khóa chính 12
NVNhan Varchar Nhân viên nhận, khóa ngoại 12
NgayTra Datetime Ngày trả 8
SoLuong Int Số lượng 4
TinhTrang Nvarchar Tình trạng 50
MaPhong Varchar Mã phòng, khóa ngoại 12
- Bảng tblPhong: Lưu thông tin về các phòng
Colunm Name Data Type Description Length Allow Null
MaPhong Varchar Mã phòng, khóa chính 12 Not Null
TenPhong Nvarchar Tên phòng 50
- Bảng tblNhanVien: Lưu thông tin về các nhân viên
Colunm Name Data Type Description Length Allow Null
MaNV Varchar Mã nhân viên, khóa chính 12 Not Null
TenNV Nvarchar Tên nhân viên 50
ChucVu Nvarchar Chức vụ 50
MaPhong VarChar Mã phòng, khóa ngoại 12
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLTB và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLTB
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Nhập thiết bị

140
Tập bài giảng Lập trình cơ sở dữ liệu

- Hiển thị tất cả danh sách các phiếu nhập thiết bị.
- Nhân viên quản lý có thể thực hiện lập phiếu nhập, sửa thông tin phiếu nhập, xóa
thông tin phiếu nhập, thoát khỏi chương trình. Khi chọn các nút sẽ hiện thị thông báo
tương ứng yêu cầu người dùng xác nhận có thực hiện tiếp hay không.
- Mã phiếu nhập sẽ tự động tăng lên khi thêm một phiếu nhập và số lượng thiết bị
trong bảng tblThietBi sẽ tăng lên dựa vào số lượng đã có cộng với số lượng nhập vào.
- Kiểm tra số lượng nhập nhập vào là số, nếu nhập không đúng thì thông báo cho
người dùng biết nhập không đúng kiểu dữ liệu.
b) Mượn thiết bị

Yêu cầu:
- Liệt kê tất cả danh sách thiết bị đang được mượn.
- Khi mượn thiết bị thì số lượng thiết bị có phải lớn hơn hoặc bằng với số lượng thiết
bị mượn và tình trạng thiết bị phải là tốt. Số lượng thiết bị có trong bảng tblThietBi sẽ
giảm theo số lượng thiết bị mượn.
- Khi thiết bị trả thì có thể xóa thông tin phiếu mượn đi.
- Kiểm tra số lượng mượn nhập vào là số, nếu nhập không đúng thì thông báo cho
người dùng biết nhập không đúng kiểu dữ liệu.

141
Tập bài giảng Lập trình cơ sở dữ liệu

- Khi chọn các nút sẽ hiện thị thông báo tương ứng yêu cầu người dùng xác nhận có
thực hiện tiếp hay không.
c) Trả thiết bị

Yêu cầu:
- Hiển thị tất cả danh sách phiếu trả thiết bị.
- Khi thiết bị được trả, xem xét tình trạng thiết bị là tốt hay hỏng để liệt kê vào dạng
tình trạng nào; số lượng trả sẽ được cập nhập lại bảng tblThietBi dựa vào tình trạng của
thiết bị trả.
- Kiểm tra số lượng trả vào là số, nếu nhập không đúng thì thông báo cho người dùng
biết nhập không đúng kiểu dữ liệu.
- Khi chọn các nút sẽ hiện thị thông báo tương ứng yêu cầu người dùng xác nhận có
thực hiện tiếp hay không.
Câu 5: Cho CSDL quản lý nhân sự (QLNS) gồm các bảng sau:
Bảng tblPhongBan: Lưu thông tin về phòng ban
Colunm Name Data Type Description Length Allow Null
MaPhongBan Char Khóa chính của bảng 12 Not Null
TenPhongBan Nvarchar Tên phòng ban 25
SoDTPB Char Số điện thoại phòng ban 12
Bảng tblNhanVien: Lưu thông tin về nhân viên
Colunm Name Data Type Description Length Allow Null
MaNhanVien Char Mã nhân viên, khóa chính 12 Not Null
của bảng
HoTenNhanVien Nvarchar Họ và tên của nhân viên 50
MaPhongBan Char Mã phòng ban, khóa ngoại 12 Not Null
MaChucVu Char Mã chức vụ, khóa ngoại 12 Not Null
SCMND Char Số chứng minh nhân dân 10
DiaChi Nvarchar Địa chỉ 50
GioiTinh Char Giới tính 5
QueQuan Nvarchar Quê quán 50
142
Tập bài giảng Lập trình cơ sở dữ liệu

Colunm Name Data Type Description Length Allow Null


NgaySinh Datetime Ngày tháng năm sinh 8
SoDT Char Số điện thoại dùng để liên 12
lạc
NgayVaoLam Datetime Ngày vào làm 8
SoBHYT Nvarchar Số bảo hiểm y tế 11
SoBHXH Nvarchar Số bảo hiểm xã hội 11
HinhAnh Nvarchar Hình ảnh tương ứng của 50
từng nhân viên
GhiChu Nvarchar Ghi chú 50
Bảng tblChucVu: Lưu thông tin về chức vụ
Colunm Name Data Type Description Length Allow Null
MaChucVu Char Mã chức vụ, khóa chính 12 Not null
TenChucVu Nvarchar Tên chức vụ 20
PhuCapChucVu Money Phụ cấp chức vụ 9
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLNS và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLNS
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ado.net entity data model
a) Quản lý nhân viên

Yêu cầu:
- Xem danh sách tất cả nhân viên trong công ty.
- Thực hiện thêm, xóa, sửa thông tin nhân viên.
- Khi chọn vào Combobox Phòng ban thì sẽ hiển thị lên danh sách những nhân viên
trong phòng ban lên trên listBox.
- Khi chọn nút sắp xếp thì danh sách nhân viên được sắp xếp theo tên.

143
Tập bài giảng Lập trình cơ sở dữ liệu

- Khi chọn nút thoát sẽ hiện lên một thông báo “Bạn có muốn thoát khỏi chương trình
không?”.
- Khi chọn nút thêm sẽ hiện lên một thông báo “Bạn có muốn thêm nhân viên vào
trong cơ sở dữ liệu không?”.
- Khi chọn nút sửa sẽ hiện lên một thông báo “Bạn có muốn sửa thông tin của nhân
viên trong cơ sở dữ liệu không?”.
b) Quản lý phòng ban

Yêu cầ u:
- Khi Form load: Thông tin trong bảng tblPhongBan đươ ̣c hiể n thị trong
DataGridview
- Nút “Về đầu”: Di chuyển con trỏ về dòng đầu tiên trên DataGridview
- Nút “Về cuối”: Di chuyển con trỏ về dòng cuối cùng trên DataGridview
- Nút “Tiếp”: Di chuyển con trỏ về dòng tiếp theo trên DataGridview
- Nút “Trước”: Di chuyển con trỏ về dòng trước trên DataGridview
- Nút “Thêm”: Khi người dùng chọn nút “Thêm” thì nút “Thêm” trở thành nút “Lưu”,
nút “Sửa” trở thành nút “Hủy”, thêm dòng trống vào DataGridView:
+ Sau khi người dùng nhâ ̣p các thông tin về ưu tiên, chọn nút “Lưu” thì mã phòng
ban, tên phòng ban, điểm cộng sẽ được lưu được bảng tblPhongBan trong cơ sở dữ liê ̣u;
đồ ng thời cập nhật thông tin vừa nhâ ̣p lên DataGridview, nút “Lưu” trở thành nút
“Thêm”, nút “Hủy” trở thành nút “Sửa”.
+ Sau khi người dùng sửa la ̣i các thông tin trên DataGridview, chọn nút “Lưu” thì lưu
các thông tin được sửa vào bảng tblPhongBan trong cơ sở dữ liê ̣u; Đồ ng thời cập nhật
la ̣i thông tin lên DataGridview, nút “Lưu” trở thành nút “Thêm”, nút “Hủy” trở thành
nút “Sửa”.
- Nút “Sửa”: Khi kích cho ̣n một dòng trên DataGridview, chọn nút “Sửa” thì nút
“Thêm” trở thành nút “Lưu”, nút “Sửa” trở thành nút Hủy.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mô
̣ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nếu người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
Câu 6: Cho CSDL quản lý thuê bằng đĩa (QLBD) gồm các bảng sau:
BD(MaBD, Tenbangdia, Soluong): Lưu thông tin về băng đĩa
KH(MaKH, Hoten, Dienthoai): Lưu thông tin về khách hàng thuê băng đĩa.

144
Tập bài giảng Lập trình cơ sở dữ liệu

THUE(MaKH, MaBD, Soluongthue, Ngaythue, Songaythue): Lưu thông tin về việc


cho thuê băng đĩa.
Trong đó: MaBD-Mã băng đĩa, Tenbangdia-Tên băng đĩa, Soluong-Số lượng băng
đĩa, MaKH-Mã khách hàng, Hoten-Họ tên, Dienthoai-Điện thoại, Soluongthue-Số
lượng thuê, Ngaythue-Ngày thuê, Songaythue-Số ngày thuê.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLBD và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLBD
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý băng đĩa

Yêu cầ u:
- Khi Form load: Thông tin trong bảng BD đươ ̣c hiể n thị trong DataGridview “Thông
tin chi tiết băng đĩa”.
- Nút “Nhâ ̣p”: Nhâ ̣p các thông tin Mã băng đĩa, tên băng đĩa, số lượng vào bảng BD
trong cơ sở dữ liê ̣u, đồ ng thời cập nhật thông tin vừa nhập lên DataGridview.
- Nút “Sửa”: Khi kić h cho ̣n một dòng trên DataGridview “Thông tin chi tiết băng đĩa”
thì thông tin của dòng đó được hiển thi lêṇ các textbox trong phần “Nhập thông tin băng
đĩa”. Sau khi người dùng sửa la ̣i các thông tin trên các textbox, chọn nút “Sửa” thì lưu
các thông tin được sửa vào bảng BD trong cơ sở dữ liê ̣u, đồ ng thời cập nhật la ̣i thông
tin lên DataGridview.
- Nút “Xóa”: Khi kić h cho ̣n một dòng trên DataGridview “Thông tin chi tiết băng
đĩa” thì thông tin của dòng đó được hiể n thi lên
̣ các textbox trong phần “Nhập thông tin
băng đĩa”. Khi người dùng chọn nút “Xóa” thì xóa dòng tương ứng ở bảng BD trong cơ
sở dữ liê ̣u, đồ ng thời cũng xóa dòng đó trên DataGridview.

145
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiể n thi mô
̣ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nế u người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
b) Quản lý khách hàng thuê băng đĩa

Yêu cầ u:
- Khi Form load: Thông tin trong bảng BD đươ ̣c hiể n thị trong DataGridview “Chi
tiế t băng đĩa”. Thông tin mã băng đĩa trong bảng BD được load lên combobox “Mã băng
đĩa”.
- Nút “Xem theo mã băng đĩa”: Khi người dùng cho ̣n trong combo “Mã băng đĩa” rồ i
chọn nút “Xem theo mã băng đĩa”, thông tin về các băng đĩa sẽ đươ ̣c hiể n thi ̣ trong
DataGridview “Chi tiế t băng đĩa”.
- Nút “Xem theo tên băng đĩa”: Khi người dùng nhập tên băng đĩa trong textbox “Tên
băng đĩa” rồ i chọn nút “Xem theo tên băng đĩa”, thông tin về các băng đĩa sẽ đươ ̣c hiể n
̣
thi trong DataGridview “Chi tiết băng đĩa”.
- Nút Nhâ ̣p: Nhâ ̣p các thông tin Mã khách hàng, Ho ̣ tên, Điện thoại vào bảng KH và
mã băng đĩa, mã khách hàng, s lượng thuê vào bảng THUE trong cơ sở dữ liê ̣u, riêng
cô ̣t ngày thuê trong cơ sở dữ liê ̣u đươ ̣c nhâ ̣p theo ngày tháng hiê ̣n ta ̣i của máy tính, các
146
Tập bài giảng Lập trình cơ sở dữ liệu

cô ̣t còn la ̣i để trố ng. Đồ ng thời cập nhật thông tin vừa nhâ ̣p lên DataGridview “Chi tiế t
khách”.
- Nút Sửa: Khi kić h cho ̣n một dòng trên DataGridview “Chi tiế t khách” thì thông tin
của dòng đang chọn trên DataGridview “Chi tiế t khách” được hiện lên các textbox và
combobox trong phần “Thông tin khách thuê”. Sau khi người dùng sửa la ̣i các thông tin
trên các textbox và combobox, chọn nút “Sửa” thì sẽ lưu lại các thông tin được sửa vào
bảng KH, THUE trong cơ sở dữ liê ̣u, đồ ng thời cập nhật thông tin vừa sửa lên
DataGridview “Chi tiế t khách”.
- Nút Xóa: Khi kić h cho ̣n một dòng trên DataGridview “Chi tiế t khách” thì thông tin
của dòng đang chọn trên DataGridview “Chi tiế t khách” được hiện lên các textbox và
combobox trong phần “Thông tin khách thuê”. Khi người dùng chọn nút “Xóa” thì xóa
dòng tương ứng ở bảng THUE trong cơ sở dữ liê ̣u, đồ ng thời cũng xóa dòng đó trên
DataGridview “Chi tiế t khách”.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mô ̣ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nếu người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
c) Thanh toán thuê băng đĩa khách hàng

Yêu cầu:
- Khi Form load: Thông tin mã băng đĩa trong bảng BD được load lên Combobox
“Mã băng đĩa”.
- Nút “Tìm kiếm theo mã băng đĩa”: Khi người dùng cho ̣n trong combo “Mã băng
đĩa” rồ i chọn nút “Tìm kiế m theo mã băng đĩa”, thông tin về khách hàng thuê băng đĩa
đó se ̃ được hiể n thi trong
̣ DataGridview “Chi tiết khách hàng thanh toán”.
- Nút “Tim̀ kiế m theo ho ̣ tên”: Khi người dùng nhập họ tên trong textbox “Họ tên
khách” rồ i chọn nút “Tìm kiếm theo họ tên”, thông tin về khách hàng se ̃ đươ ̣c hiể n thi ̣
trong DataGridview “Chi tiế t khách hàng thanh toán”.
147
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Tính tiề n”: Khi nhọn nút “Tính tiề n” thì sẽ hiể n thi ̣ thông tin mã băng đĩa
khách thuê, số ngày khách thuê (ngày hiê ̣n ta ̣i khách thanh toán - ngày khách thuê+1),
tổ ng tiề n khách phải thanh toán (số ngày khách thuê * 5000) lên form. Đồ ng thời cập
nhật thông tin số ngày khách thuê và thành tiền vào bảng KH và DataGridview “Chi tiết
khách hàng thanh toán”.
- Nút “Thoát”: Khi người dùng chọn nút “Thoát” thì hiển thi mộ ̣t hô ̣p thoa ̣i hỏi người
dùng có chắ c chắ n muố n thoát không; nếu người dùng nhấ n nút Yes thì cho thoát khỏi
form, nế u không thì không cho thoát.
Câu 7: Cho CSDL quản lý bán thuốc (QLBT) gồm các bảng sau:
Thuoc(MaThuoc, TenThuoc, CongDung, NgaySanXuat, NgayHetHanDung,
SoLuongSanXuat, DonViTinh): Lưu trữ thông tin về thuốc
KhachHang(MaKhachHang, TenKhachHang, DiaChi, SoDienThoai): Lưu trữ thông
tin về khách hàng
DonHang(MaDonHang, MaKhachHang, NguoiLap, NgayLap, NgayNhanHang):
Lưu trữ thông tin về đơn hàng
ChiTietDonHang(MaDonHang, MaThuoc, SoLuong, DonViTinh, DonGia): Lưu trữ
thông tin về chi tiết đơn hàng
Trong đó: MaThuoc-Mã thuốc, TenThuoc-Tên thuốc, CongDung-Công dụng,
NgaySanXuat-Ngày sản xuất, NgayHetHanDung-Ngày hết hạn dùng,
SoLuongSanXuat-Số lượng sản xuất, DonViTinh-Đơn vị tính. MaKhachHang-Mã
khách hàng, TenKhachHang-Tên khách hàng, DiaChi-Địa chỉ, SoDienThoai-Số điện
thoại, NguoiLap-Người lập, NgayLap-Ngày lập, NgayNhanHang-Ngày nhận hàng,
SoLuong-Số lượng, DonViTinh-Đơn vị tính, DonGia-Đơn giá.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLBT và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLBT
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý đơn hàng

Yêu cầ u:
- Khi Form load: Bản ghi đầu tiên trong bảng DonHang đươ ̣c hiể n thi lên
̣ trên các đối
tượng trong Form, hiển thị danh sách mã khách hàng từ bảng KhachHang trong
ComboBox mã khách hàng.
- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng DonHang

148
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng DonHang
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng DonHang
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng DonHang
- Nút ”Xóa”: Xóa các bản ghi liên quan trong bảng ChiTietDonHang và bản ghi hiện
hành trong bảng DonHang. Yêu cầu hiển thị thông báo xác nhận xóa, các bản ghi này
chỉ được xóa nếu người sử dụng trả lời đồng ý.
b) Quản lý thuốc

Yêu cầ u:
- Khi Form load: Thông tin trong bảng Thuoc đươ ̣c hiể n thị trong DataGridview
- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng Thuoc
- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng Thuoc
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng Thuoc
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng Thuoc
- Nút ”Xóa”: Hiển thị thông báo xác nhận xóa bản ghi, nếu người sử dụng đồng ý xóa
thì bản ghi hiện hành sẽ bị xóa khỏi lưới thuốc và cập nhật vào bảng Thuoc.
c) Quản lý bán thuốc

Yêu cầ u:

149
Tập bài giảng Lập trình cơ sở dữ liệu

- Khi Form load: Bản ghi đầu tiên trong bảng Thuoc đươ ̣c hiể n thi ̣ lên trên các đối
tượng trong Form, hiển thị danh sách mã đơn hàng của bảng DonHang trong ComboBox
Mã đơn hàng
- Khi người sử dụng chọn một mã đơn hàng thì thông tin về đơn hàng đó sẽ được hiển
thị trong phần Đơn hàng và chi tiết đơn hàng sẽ được hiển thị trong lưới.
- Nút “Thêm”: Cho phép người sử dụng bổ sung bản ghi mới và cập nhật vào bảng
ChiTietDonHang cho một đơn hàng đã chọn.
d) Tìm kiếm bán thuốc

Yêu cầ u:
- Khi Form load: Thông tin trong bảng Thuoc đươ ̣c hiể n thị trong DataGridview
- Nút “Tìm“: Tùy theo thông tin tìm kiếm người sử dụng đã thiết lập, chương trình
tiến hành lọc trên bảng Thuoc và hiển thị kết quả lên DataGridview
- Nút “Hiện hết”: Hiện hết các bản ghi thỏa mãn điều kiện trong bảng Thuoc lên
DataGridview
e) Lập đơn hàng

Yêu cầ u:
- Khi Form load: Thông tin trong bảng Khachhang đươ ̣c hiể n thị trong DataGridview
- Khi người dùng chọn một khách hàng trên DataGridview Khách hàng thì thông tin
liên quan đến khách hàng đó trong bảng DonHang sẽ được hiện thị lên DataGridview
DonHang.

150
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Thêm khách”: Cho phép người sử dụng bổ sung một bản ghi mới vào lưới
khách hàng, với mã khách hàng được gán tự động gồm 2 ký tự “KH” và số thứ tự bản
ghi.
Câu 8: Cho CSDL quản lý thư viện (QLTV) gồm các bảng sau:
Sach(MaSach, TenSach, TacGia, NhaXuatBan, NamXB): Lưu thông tin về sách
DocGia(MaDocGia, HoTen, DiaChi, SoDienThoai): Lưu thông tin về độc giả
PhieuMuonSach(SoPhieu, MaDocGia, HoTenNhanVien, NgayMuon): Lưu thông tin
về phiếu mượn sách
ChiTietPhieuMuon(SoPhieu, MaSach, NgayHenTra, NgayTra): Lưu thông tin về chi
tiết phiếu mượn
Trong đó: MaSach-Mã sách, TenSach-Tên sách, TacGia-Tác giả, NhaXuatBan-Nhà
xuất bản, NamXB-Năm xuất bản, MaDocGia-Mã độc giả, HoTen-Họ tên, DiaChi-Địa
chỉ, SoDienThoai-Số điện thoại, SoPhieu-Số phiếu, HoTenNhanVien-Họ tên nhân viên,
NgayMuon-Ngày mượn, NgayHenTra-Ngày hen trả, NgayTra-Ngày trả
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLTV và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLTV
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý độc giả

Yêu cầu:
- Khi Form load: Bản ghi đầu tiên trong bảng DocGia đươ ̣c hiể n thi ̣ lên trên các đối
tượng trong Form
- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng DocGia
- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng DocGia
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng DocGia
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng DocGia
- Nút ”Xóa”: Cho phép người sử dụng bổ sung một bản ghi mới vào bảng DocGia,
đảm bảo không có hai độc giả trùng mã.
b) Quản lý sách

151
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầu:
- Khi Form load: Thông tin trong bảng Sach đươ ̣c hiể n thi ̣trong DataGridview
- Nút ”Xóa”: Hiển thị thông báo xác nhận xóa bản ghi, nếu người sử dụng đồng ý xóa
thì tất cả các bản ghi có liên quan trong bảng ChiTietPhieuMuon và bản ghi hiện hành
trong bảng Sach sẽ bị xóa.
c) Quản lý phiếu mượn

Yêu cầu:
- Khi Form load: Bản ghi đầu tiên trong bảng PhieuMuonSach đươ ̣c hiể n thi lên
̣ trên
các đối tượng trong Form, hiển thị danh sách mã độc giả từ bảng DocGia trong
ComboBox mã độc giả.
- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng PhieuMuonSach
- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng PhieuMuonSach
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng PhieuMuonSach
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng PhieuMuonSach
- Nút “Thêm”: Cho phép người sử dụng bổ sung một bản ghi mới vào bảng
PhieuMuon, đảm bảo không có hai phiếu mượn trùng mã.
d) Quản lý chi tiết phiếu mượn

- Khi Form load: Bản ghi đầu tiên trong bảng PhieuMuonSach đươ ̣c hiể n thi lên
̣ trên
các đối tượng trong Form, hiển thị chi tiết phiếu mượn tương ứng trong bảng
ChiTietPhieuMuon lên DataGridView.

152
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng PhieuMuonSach và các
bản ghi tương ứng trong bảng ChiTietPhieuMuon trên DataGridView.
- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng PhieuMuonSach
và các bản ghi tương ứng trong bảng ChiTietPhieuMuon trên DataGridView.
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng PhieuMuonSach và
các bản ghi tương ứng trong bảng ChiTietPhieuMuon trên DataGridView.
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng PhieuMuonSach và các bản
ghi tương ứng trong bảng ChiTietPhieuMuon trên DataGridView.
- Nút “Thêm”: cho phép người sử dụng bổ sung bản ghi mới và cập nhật vào bảng
PhieuMuon và bảng ChiTietPhieuMuon, đảm bảo không có hai phiếu mượn.
e) Quản lý tìm kiếm sách

Yêu cầu:
- Khi Form load: Thông tin trong bảng Sach đươ ̣c hiể n thị trong DataGridview; đưa
tất cả các cuốn sách có trong bảng Sach vào ComboBox Tên sách, những tên sách trùng
nhau chỉ xuất hiện một lần trong danh sách; đưa “Tất cả” và tên của tất cả các cuốn sách
có trong bảng Sach vào ComboBox Tên sách, những tên sách trùng nhau chỉ xuất hiện
một lần trong danh sách.
- Nút “Tìm“: Tùy theo thông tin tìm kiếm người sử dụng đã thiết lập, chương trình
tiến hành lọc trên bảng Thuoc và hiển thị kết quả lên DataGridview
f) Nhập chi tiết phiếu mượn

Yêu cầu:
- Khi Form load: Thông tin trong bảng Sach đươ ̣c hiể n thi ̣ trong DataGridview
“Sách”; thông tin trong bảng ChiTietPhieuMuon đươ ̣c hiể n thi trong
̣ DataGridview “Chi
153
Tập bài giảng Lập trình cơ sở dữ liệu

tiết phiếu mượn”, đưa tất cả các số phiếu có trong bảng PhieuMuon vào ComboBox Số
phiếu.
- Nút “Mượn”: Khi người sử dụng chọn một số phiếu và chọn một cuốn sách trong
DataGridview “Sách” rồi nhấn vào nút mượn thì sẽ bổ sung một bản ghi mới vào
DataGridview “Chi tiết phiếu mượn” với số phiếu và mã sách đã chọn được nhập tự
động.
- Nút “Lưu”: Cập nhật thông tin đã nhập vào bảng ChiTietPhieuMuon.
g) Nhận trả sách

Yêu cầu:
- Khi Form load: Thông tin trong bảng PhieuMuon đươ ̣c hiể n thị trong DataGridview
“Phiếu mượn”; thông tin trong bảng ChiTietPhieuMuon được hiển thi ̣ trong
DataGridview “Chi tiết phiếu mượn trả”, đưa tất cả các số phiếu có trong bảng
PhieuMuon vào ComboBox Số phiếu.
- Nút “Tìm”: Thực hiện việc tìm kiếm trên bảng PhieuMuon theo số phiếu được nhập
từ TextBox “Số phiếu” và hiển thị kết quả trên DataGridview “Phiếu mượn” và
DataGridview “Chi tiết phiếu mượn trả”.
- Nút “Trả”: Đối với những cuốn sách chưa trả, khi người sử dụng chọn nó trong
DataGridview “Chi tiết phiếu mượn trả” rồi nhấn vào nút “Trả”, chương trình tự động
điền ngày trả (ngày hiện hành) vào DataGridview “Chi tiết phiếu mượn trả” và cập nhật
bảng ChiTietPhieuMuon.
h) Lập phiếu mượn

Yêu cầu:

154
Tập bài giảng Lập trình cơ sở dữ liệu

- Khi Form load: Hiển thị mã của tất cả các độc giả trong ComboBox, Thông tin trong
bảng PhieuMuon đươ ̣c hiể n thi ̣trong DataGridview “Phiếu mượn”;
- Nút “Kiểm tra quá hạn”: Lọc ra các cuốn sách mà độc giả đó mượn quá hạn chưa
trả và hiển thị kết quả trên DataGridview “Sách mượn quá hạn chưa trả”.
- Nút “Lập phiếu”: Khi người sử dụng đã chọn mã độc giả từ ComboBox rồi nhấn
vào nút “Lập phiếu” thì sẽ bổ sung một bản ghi mới vào DataGridview “Phiếu mượn”
với mã độc giả đã chọn, ngày mượn là ngày hiện tại được tự động nhập vào
DataGridview “Phiếu mượn” và cập nhật bảng PhieuMuon.
Câu 9: Cho CSDL quản lý bán hàng (QLBH) gồm các bảng sau:
MatHang(MaMatHang, TenMatHang, XuatXu, DonViTinh): Chứa các thông tin về
mặt hàng
DaiLy(MaDaiLy, TenDaiLy, DiaChi, SoDienThoai): Chứa các thông tin về đại lý
DonHang(MaDonHang, MaDaiLy, NguoiLap, NgayLap, NgayNhanHang): Chứa các
thông tin về đơn hàng
ChiTietDonHang(MaDonHang, MaMatHang, SoLuong, Gia): Chứa các thông tin về
chi tiết đơn hàng.
Trong đó: MaMatHang-Mã mặt hàng, TenMatHang-Tên mặt hàng, XuatXu-Xuất xứ,
DonViTinh-Đơn vị tính, MaDaiLy-Mã đại lý, TenDaiLy-Tên đại lý, DiaChi-Địa chỉ,
SoDienThoai-Số điện thoại, MaDonHang-Mã đơn hàng, NguoiLap-Người lập,
NgayLap-Ngày lập, NgayNhanHang-Ngày nhận hàng, SoLuong-Số lượng, Gia-Giá.
Yêu cầu:
1) Tạo cơ sở dữ liệu với tên là QLBH và các bảng dữ liệu với kiểu dữ liệu tự chọn
phù hợp.
2) Tạo dự án đặt tên là QLBH
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model
a) Quản lý mặt hàng

Yêu cầu:
- Khi Form load: Thông tin trong bảng Mathang đươ ̣c hiể n thị trong DataGridview
- Nút “Về đầu”: Di chuyển về bản ghi đầu tiên trong bảng Mathang
- Nút “Về trước”: Di chuyển về trước bản ghi hiện hành trong bảng Mathang
- Nút “Về sau”: Di chuyển về sau bản ghi hiện hành trong bảng Mathang
- Nút “Về cuối”: Di chuyển bản ghi cuối cùng trong bảng Mathang
155
Tập bài giảng Lập trình cơ sở dữ liệu

- Nút ”Thêm”: Thêm bản ghi vào bảng Mathang.


b) Tìm kiếm mặt hàng

Yêu cầu:
- Khi Form load: Thông tin trong bảng Mathang đươ ̣c hiể n thi ̣ trong DataGridview;
mã mặt hàng trong bảng MatHang được đưa vào Combo Mã mặt hàng.
- Nếu người sử dụng chọn Mã mặt hàng thì hiển thị ComboBox cho phép người sử
dụng chọn một trong số các mã mặt hàng trong bảng MatHang và ẩn ComboBox tên
mặt hàng.
- Nếu người sử dụng chọn Tên mặt hàng thì hiển thị ComboBox tên mặt hàng cho
phép người sử dụng chọn một trong số các mặt hàng trong bảng MatHang và ẩn
ComboBox mã mặt hàng.
- Nút “Tìm”: Cho phép người sử dụng sau khi chọn tiêu chí và nhập thông tìm tìm
kiếm sẽ tiến hành lọc bảng MatHang và hiển thị những bản ghi thỏa mãn điều kiện trên
DataGridview
- Nút “Hiện hết”: Hiển thị tất cả các bản ghi trong bảng MatHang.
c) Quản lý đại lý

Yều cầu:
- Khi Form load: Thông tin trong bảng Daily đươ ̣c hiể n thi trong
̣ DataGridview
- Nút “Thêm”: Cho phép người sử dụng bổ sung một bản ghi vào bảng DaiLy sao cho
không trùng mã đại lý.
- Nút “Sửa”: Cho phép người sử dụng sửa nội dung bản ghi hiện hành sao cho không
được sửa mã đại lý.
d) Quản lý đơn hàng

156
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầu:
- Khi Form load: Thông tin trong bảng Donhang đươ ̣c hiể n thi trong
̣ DataGridview
- Nút “Thêm”: Cho phép người sử dụng bổ sung một bản ghi mới, bản ghi này chỉ
được cập nhật vào bảng DonHang nếu thỏa mãn các điều kiện sau:
+ Không trùng mã đơn hàng với các bản ghi đã có
+ Mã đại lý phải có trong bảng DaiLy
+ Ngày lập đơn hàng là ngày hiện hành của hệ thống
+ Ngày nhận hàng phải sau ngày lập đơn hàng
e) Nhập chi tiết đơn hàng

Yêu cầu:
- Khi Form load: Thông tin trong bảng Donhang đươ ̣c hiể n thi ̣ trong DataGridview
“Đơn hàng”; hiển thị mã các đơn hàng trong ComboBox Mã đơn hàng
- Khi người sử dụng chọn một mã đơn hàng từ danh sách này, chương trình sẽ tiến
hành tìm kiếm trong bảng DonHang, xác lập bản ghi hiện hành trong lưới đơn hàng là
bản ghi tìm được.
- Nút “Thêm”: Cho phép người sử dụng bổ sung một bản ghi mới vào bảng
ChiTietDonHang với một đơn hàng đã được chọn.
f) Hủy đơn hàng

157
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầu:
- Khi Form load: Hiển thị danh sách mã đại lý trong ComboBox mã đại lý, sao cho
khi người dùng chọn một mã đại lý từ danh sách này thì thông tin về đại lý đó và các
đơn hàng tương ứng được hiển thị trên form.
- Nút “Xóa”: Cho phép xóa tất cả các đơn hàng được chọn trong DataGridview của
bảng DonHang của một đại lý đã chọn.
g) Lập đơn hàng theo đại lý

Yêu cầu:
- Khi Form load: Hiển thị danh sách mã đại lý trong ComboBox mã đại lý, sao cho
khi người dùng chọn một mã đại lý từ danh sách này thì thông tin về đại lý đó, các đơn
hàng và chi tiết đơn hàng tương ứng được hiển thị trên form.
- Nút “Nhập chi tiết đơn hàng”: Cho phép người sử dụng bổ sung một bản ghi mới
và cập nhật vào bảng ChiTietDonHang cho một đơn hàng đã chọn.
h) Lập chi tiết đơn hàng
158
Tập bài giảng Lập trình cơ sở dữ liệu

Yêu cầu:
- Khi Form load: Hiển thị danh sách mã đơn hàng trong ComboBox mã đơn hàng,
sao cho khi người dùng chọn một mã đơn hàng từ danh sách này thì thông tin về đơn
hàng đó và chi tiết đơn hàng tương ứng được hiển thị trên form.
- Nút “Thêm”: Cho phép người sử dụng bổ sung một bản ghi mới vào bảng
ChiTietDonHang với một đơn hàng đã được chọn.
Câu 10: Để quản lý kho hàng cho một cửa hàng bán điện thoại di động, ta tạo ra một
cơ sở dữ liệu có tên là QLKH có 2 bảng:
HANGSX(mahang, tenhang): Lưu thông tin về hãng sản xuất
DIENTHOAI(ma, ten, dongia, tonkho, mahang): Lưu thông tin về điện thoại di động.
Trong đó: mahang-Mã hãng điện thoại; tenhang-Tên hãng điện thoại; ma-Mã điện
thoại, ten-Tên điện thoại, dongia-Đơn giá; tonkho-Tồn kho.
Yêu cầu:
1) Tạo Tạo cơ sở dữ liệu và các bảng dữ liệu với kiểu dữ liệu tự chọn phù hợp.
2) Tạo dự án
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model để thực hiện việc thêm, sửa, xóa, tìm
kiếm các thông tin về hãng sản xuất, điện thoại.
Câu 11: Để quản lý vận động viên tại một Câu lạc bộ, ta tạo ra một cơ sở dữ liệu có tên
là QLVDV có 3 bảng:
tblThanhvien(MaThanhvien, Hoten, Ngaysinh, Gioitinh, Donvi, Sothich, Diachi,
Dienthoai, Quyenhan): Lưu thông tin về các thành viên.
tblPhieu(Mahoatdong, Mathanhvien, ThoigianBD, ThoigianKT, Danhgia): Lưu
thông tin về các hoạt động của các thành viên.
tblHoatdong(Mahoatdong, Tenhoatdong, Noidung, Thoigian, Kinhphi): Lưu thông
tin về các hoạt động.
Trong đó: MaThanhvien-Mã thành viên, Hoten-Họ tên, Ngaysinh-Ngày sinh,
Gioitinh-Giới tính, Donvi-Đơn vị, Sothich-Sở thích, Diachi-Địa chỉ, Dienthoai-Điện
thoại, Quyenhan-Quyền hạn, Mahoatdong-Mã hoạt động, Mathanhvien-Mã thành viên,
ThoigianBD-Thời gian bắt đầu, ThoigianKT-Thời gian kết thúc, Danhgia-Đánh giá,

159
Tập bài giảng Lập trình cơ sở dữ liệu

Tenhoatdong-Tên hoạt động, Noidung-Nội dung, Thoigian-Thời gian, Kinhphi-Kinh


phí.
Yêu cầu:
1) Tạo cơ sở dữ liệu và các bảng dữ liệu với kiểu dữ liệu tự chọn phù hợp.
2) Tạo dự án
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model để thực hiện việc thêm, sửa, xóa, tìm
kiếm các thông tin về thành viên, hoạt động, và các hoạt động của các thành viên.
Câu 12: Để quản lý cho thuê xe tự lái tại một Công ty, ta tạo ra một cơ sở dữ liệu có tên
là QLTX có 3 bảng:
tblXe(Maxe, Sokhung, Somay, HangSX, NamSX, SoLuong) : Lưu thông tin về xe.
tblKH(MaK,TenK, Coquan, Diachi, Tel): : Lưu thông tin về khách hàng
tblYeuCau(Maxe, MaK, Ngaymuon, Ngaytra): : Lưu thông tin về yêu cầu mượn xe
của khách hàng.
Trong đó: Maxe-Mã xe, Sokhung-Số khung, Somay-Số máy, HangSX-Hãng sản
xuất, NamSX-Năm sản xuất, SoLuong-Số lượng, MaK-Mã khách,TenK-Tên khách,
Coquan-Cơ quan, Diachi-Địa chỉ, Tel-Điện thoại, Ngaymuon-Ngày mượn, Ngaytra-
Ngày trả.
Yêu cầu:
1) Tạo cơ sở dữ liệu và các bảng dữ liệu với kiểu dữ liệu tự chọn phù hợp.
2) Tạo dự án
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model để thực hiện việc thêm, sửa, xóa, tìm
kiếm các thông tin về hoạt động cho thuê xe của công ty.
Câu 13: Trong dự án quản lý cán bộ của một cơ quan có cơ sở dữ liệu QLCB gồm các
bảng CSDL có cấu trúc như sau:
HOSO
Tên trường Giải thích
manv Mã nhân viên
Hoten Họ và tên nhân viên
Gioitinh Giới tính
Ngaysinh Ngày sinh
Diachi Địa chỉ
Ngayvn Ngày vào ngành
MaNg Mã ngạch
MaCV Mã chức vụ
PHONGBAN
Tên trường Giải thích
Maphong Mã phòng
Tenphong Tên phòng
Vitri Vị trí phòng
NGACH

160
Tập bài giảng Lập trình cơ sở dữ liệu

Tên trường Giải thích


MaNg Mã ngạch
TenNg Tên ngạch
CHVU
Tên trường Giải thích
MaCV Mã chức vụ
TenCV Tên chức vụ
Hesophucap Hệ số phụ cấp
LUONG
Tên trường Giải thích
manv Mã nhân viên
maphong Mã phòng
Hesoluong Hệ số lương
ngayLL Ngày lên lương lần cuối
Yêu cầu:
1) Tạo cơ sở dữ liệu và các bảng dữ liệu với kiểu dữ liệu tự chọn phù hợp.
2) Tạo dự án
3) Xây dựng mô hình LINQ to SQL
4) Xây dựng mô hình EDM
5) Thiết kế các form theo mẫu và lập trình các nút lệnh sử dụng ADO.NET, sử dụng
LINQ, sử dụng ADO.NET Entity Data Model để thực hiện việc thêm, sửa, xóa, tìm
kiếm các thông tin về lương của nhân viên.

161

You might also like