Phần 4: Lập trình Cơ sở dữ liệu với C#
Lập trình Cơ sở dữ liệu là một phần rất quan trọng trong lập trình ứng dụng, nó là trung gian kết nối giữa người sử dụng với cơ sở dữ liệu.
Với công nghệ ADO.NET chúng ta có một chuẩn thống nhất để lập trình thao tác với các nguồn cơ sở dữ liệu khác nhau như Access, MySQL, SQL Server, Oracle… cũng như lập trình ứng dụng với dạng WinForm và WebForm.
Trong bài này chúng ta sẽ đi vào một bài tập cụ thể để tìm hiểu các đối tượng quan trọng trong ADO.NET để lập trình với CSDL như: Connection, Command, DataReader, DataAdapter, DataSet để kết nối đến hệ quản trị CSDL SQL Server.
Nội dung
- Yêu cầu bài toán
- Tổng quan Các đối tượng trong ADO.NET
- Thực hiện câu lệnh Select, hiển thị dữ liệu lên DataGrid
- Thực hiện các câu lệnh Insert, Update, Delete dữ liệu
- Sử dụng Stored Procedure
- Lưu thông tin cấu hình trong file config
- Tham khảo thêm
Yêu cầu bài toán
Lập trình quản lý cơ sở dữ liệu QLBanHang có các bảng:
tblMatHang( MaSP nchar(5), TenSP nvarchar(30), NgaySX Date, NgayHH Date, DonVi nvarchar(10), DonGia float , GhiChu nvarchar(200))
tblNhaCC(MaNhaCC nchar(5), TenNhaCC nvarchar(50), DiaChi nvarchar(200), MaSoThue nvarchar(15), TaiKhoan nvarchar(15), DienThoai nvarchar(11))
tblHangNhap(MaSP nchar(5), MaNhaCC nchar(5), SoLuong int, DonGia float, SoHD nvarchar(10), NgayGH Date)
Hãy xây dựng giao diện và các chức năng Thêm mới, Sửa, Xoá, Tìm kiếm của các bảng trên tương tự như sau.
>Xem hướng dẫn tạo Database trong VisualStudio
Tổng quan Các đối tượng trong ADO.NET
1. Các .Net Data Provider trong ADO.Net
Sử dụng NameSpace System.Data để lập trình với ADO.NET
Các .Net Data Provider được sử dụng để kết nối tới cơ sở dữ liệu, thực thi các câu lệnh truy vấn (SQL) và lấy dữ liệu. Dữ liệu trả về có thể được xử lý trực tiếp, đặt trong đối tượng DataSet, được kết hợp với dữ liệu từ nhiều nguồn hoặc gửi dữ liệu giữa các tầng (tiers) trong mô hình lập trình nhiều tầng (N-Tier).
Trong .Net Framework có các .Net Data Provider mặc định sau:
- .NET Data Provider cho SQL Server: sử dụng namespace System.Data.SqlClient
- .NET Data Provider cho OLE DB: sử dụng namespace System.Data.OleDb
- .NET Data Provider cho ODBC: sử dụng namespace System.Data.Odbc
- .NET Data Provider cho Oracle: sử dụng namespace System.Data.OracleClient
- EntityClient Provider: cung cấp truy cập dữ liệu cho các ứng dụng dạng Entity Data Model (EDM), sử dụng namespace System.Data.EntityClient
- .NET Data Provider cho SQL Server Compact 4.0: cung cấp truy cập dữ liệu cho Microsoft SQL Server Compact 4.0, sử dụng namespace System.Data.SqlServerCe
2. Các đối tượng trong .Net Data Provider
- Connection: thiết lập kết nối tới nguồn dữ liệu
- Command: thực thi các câu lệnh truy vấn với nguồn dữ liệu từ một Connection
- DataReader: cung cấp một luồng (stream) dữ liệu chỉ đọc từ nguồn dữ liệu
- DataAdapter: đặt dữ liệu vào DataSet và cập nhật dữ liệu từ DataSet về nguồn dữ liệu
3. Các phương thức và thuộc tính quan trọng
a. Connection
- Thuộc tính ConnectionString: truyền vào chuỗi kết nối tới nguồn dữ liệu
- Phương thức Open: mở kết nối
- Phương thức Close: đóng kết nối
b. Command
- Thuộc tính CommandText: truyền vào câu lệnh SQL hoặc tên Stored procedure
- Thuộc tính CommandType: kiểu câu lệnh SQL là StoredProcedure,
TableDirect hay Text - Thuộc tính Connection: truyền vào đối tượng Connection
- Phương thức ExecuteReader: thực thi với câu lệnh SQL Select và trả về luồng dữ liệu qua đối tượng DataReader
- Phương thức ExecuteScalar: thực thi câu lệnh SQL Select và trả về một giá trị ở hàng đầu tiên và cột đầu tiên. Thích hợp với câu lệnh Select dạng thống kê như Count, Sum, AVG …
- Phương thức ExecuteNonQuery: thực thi câu lệnh SQL như Insert, Update, Delete … và không trả về kết quả
- Phương thức ExecuteXMLReader: thực thi câu lệnh truy vấn với các câu lệnh cho XML
c. DataReader
- Phương thức Read: đọc các hàng dữ liệu
d. DataAdapter
- Phương thức Fill: đổ dữ liệu từ nguồn dữ liệu vào DataSet
- Phương thức Update: cập nhật dữ liệu từ DataSet tới nguồn dữ liệu
Thực hiện câu lệnh Select, hiển thị dữ liệu lên DataGrid
>>Xem hướng dẫn phần thiết kế giao diện
Để lập trình với CSDL, bạn cần biết các câu lệnh cơ bản để thao tác với CSDL như SELECT, INSERT, UPDATE, DELETE. Phần này chúng ta sẽ lập trình để hiển thị dữ liệu lên DataGridView
Cú pháp câu lệnh Select
SELECT danh_sách_các_cột FROM tên_bảng
WHERE danh_sách_các_điều_kiện
Các bước
Bước 1:Khai báo .Net Data Provider cho SQL Server
using System.Data.SqlClient;
Bước 2: Tạo đối tượng Connection, khởi gán chuỗi kết nối, mở kết nối
//Tạo đối tượng Connection
SqlConnection con = new SqlConnection();
//Truyền vào chuỗi kết nối tới cơ sở dữ liệu
//Sử dụng Application.StartupPath để lấy đường dẫn tới thư mục chứa file chạy chương trình
con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=" + Application.StartupPath + @"\QLBanHang.mdf;Integrated Security=True;User Instance=True";
con.Open(); // mở kết nối
Bước 3: Khai báo đối tượng DataAdapter để Fill dữ liệu vào DataSet
//Lấy toàn bộ dữ liệu từ bảng tblMatHang
String sql = "Select * from tblMatHang";
//tạo đối tượng DataSet
DataSet ds = new DataSet();
//Khởi tạo đối tượng DataAdapter và cung cấp vào câu lệnh SQL và đối tượng Connection
SqlDataAdapter dap = new SqlDataAdapter(sql,con);
//Dùng phương thức Fill của DataAdapter để đổ dữ liệu từ DataSource tới DataSet
dap.Fill(ds);
Bước 4: Gắn dữ liệu lên DataGrid
//Gắn dữ liệu từ DataSet lên DataGridView
dgvKetQua.DataSource = ds.Tables[0];
dgvKetQua.Refresh();
>>Xem hướng dẫn phần hiển thị dữ liệu lên DataGridView
Thực hiện các câu lệnh Insert, Update, Delete dữ liệu
Cú pháp câu lệnh Insert
INSERT INTO tên_bảng(danh_sách_các_cột)
VALUES (danh_sách_các_giá_trị)
Các bước
Bước 1: Khởi tạo đối tượng Connection giống bước 2 phần trên
Bước 2: Khởi tạo đối tượng Command và thực thi câu lệnh Insert
//Tạo câu lệnh truy vấn Insert lấy dữ liệu từ các Control trên Form thiết kế
sql = "INSERT INTO tblMatHang(MaSP,TenSP,NgaySX,NgayHH,DonVi,DonGia,GhiChu)VALUES (";
sql += "N'" + txtMaSP.Text + "',N'" + txtTenSP.Text + "','" + dtpNgaySX.Value.Date + "','" + dtpNgayHH.Value.Date + "',N'" + txtDonVi.Text + "',N'" + txtDonGia.Text + "',N'" + txtGhiChu.Text + "')";
//Thực thi câu lệnh SQL sử dụng đối tượng Command
SqlCommand cmd = new SqlCommand(sql, con);
cmd.ExecuteNonQuery();
Cú pháp câu lệnh Update
UPDATE tên_bảng
SET
tên_cột_1 = giá_trị_1,
tên_cột_2 = giá_trị_2,
...,
tên_cột_n = giá_trị_n
[WHERE điều_kiện];
Các bước
thực hiện tương tự như phần trên, chỉ khác câu lệnh SQL Update.
Cú pháp câu lệnh Delete
DELETE FROM tên_bảng
[WHERE điều_kiện];
Các bước
thực hiện tương tự như phần trên, chỉ khác câu lệnh SQL Delete.
Sử dụng các Stored Procedure
Thay vì viết câu lệnh SQL trực tiếp trong Code chương trình, chúng ta có thể khai thác các Stored Procedure để tái sử dụng và tăng hiệu năng sử dụng Stored Procedure. Xem thêm bài về Stored Procedure.
Các bước
Bước 1: Tạo Stored Procedure trong SQL Server, giả sử đặt tên là InsertMatHang
CREATE PROCEDURE InsertMatHang
@MaSP nachr(5),
@TenSP nvarchar(30),
@NgaySX Date,
@NgaySX Date,
@DonVi nvarchar(10),
@DonGia float,
@GhiChu nvarchar(200)
AS
INSERT INTO tblMatHang(MaSP,TenSP,NgaySX,NgayHH,DonVi,DonGia,GhiChu)
VALUES(@MaSP,@TenSP,@NgaySX,@NgayHH,@DonVi,@DonGia,@GhiChu)
Bước 2: Viết code C# thực thi Stored Procedure
//B1. Tạo đối tượng Connection
SqlConnection con = new SqlConnection();
con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=" + Application.StartupPath + @"\QLBanHang.mdf;Integrated Security=True;User Instance=True";
con.Open(); // mở kết nối
//B2. Tạo đối tượng Command
SqlCommand cmd = new SqlCommand();
//Thiết lập các thuộc tính cho đối tượng Command
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "InsertMatHang";
//B3. Gắn các Parameter và giá trị cho đối tượng Command
cmd.Parameters.Add(new SqlParameter("@MaSP", txtMaSP.Text));
cmd.Parameters.Add(new SqlParameter("@TenSP", txtTenSP.Text));
cmd.Parameters.Add(new SqlParameter("@NgaySX", dtpNgaySX.Value.Date));
cmd.Parameters.Add(new SqlParameter("@NgayHH", dtpNgayHH.Value.Date));
cmd.Parameters.Add(new SqlParameter("@DonVi", txtDonVi.Text));
cmd.Parameters.Add(new SqlParameter("@DonGia", txtDonGia.Text));
cmd.Parameters.Add(new SqlParameter("@GhiChu", txtGhiChu.Text));
//B4. Thực thi Stored Procedure
cmd.ExecuteNonQuery();
Lưu thông tin cấu hình trong file config
Như phần trên bạn thấy khi khởi tạo chuỗi kết nối cho đối tượng Connection chúng ta đang đặt code cứng (hard code), sẽ không mềm dẻo khi bạn đi triển khai ứng dụng cho khách hàng. Bạn có thể lưu trữ chuỗi kết nối trong file config của ứng dụng (file có tên app.config, một dạng file xml lưu trữ toàn bộ cấu hình ứng dụng). Khi đi triển khai ứng dung, chúng ta chỉ cần mở file app.config là có thể cấu hình cho ứng dụng mà không cần phải biên dịch lại code.
Các bước
Bước 1: vào Project > Chọn Project Properties > Settings > rồi đánh Name: QLMatHangConnectionString, Type: Connection string, Value: Chọn cấu hình tới CSDL của bạn
Bước 2: cập nhật trong Code:
SqlConnection objCon = new SqlConnection();
//Lấy dữ liệu chuỗi kết nối thông qua đối tượng Properties
objCon.ConnectionString = Properties.Settings.Default.QLMatHangConnectionString;
Tham khảo thêm
- Bài giảng lập trình Cơ sở dữ liệu với ADO.NET
- Các bài học sử dụng SQL Server
- Các câu lệnh SQL căn bản
- Thiết kế giao diện và lập trình Cơ sở dữ liệu với WinForms
- Thiết kế giao diện và lập trình Cơ sở dữ liệu với WebForms
- Xây dựng chương trình quản lý bán hàng bằng C#
- Chuẩn viết code .Net
Thầy hướng dẫn lại cho em chỗ thêm dữ liệu vào CSDL
Hiện trên datagridview nhưng không lưu đc vào CSDL với ạ
Chào em,
Em đang sử dụng chuỗi kết nối theo kiểu như thế này:
con.ConnectionString = @”Data Source=.\SQLEXPRESS;AttachDbFilename=” + Application.StartupPath + @”\QLBanHang.mdf;Integrated Security=True;User Instance=True”;
hay là lưu trữ chuỗi kết nối trong file app.config?
E đang dùng kết chuỗi kết nối như thầy hướng dẫn ở bên trên
Lưu trữ chuỗi kết nối trong file app.config ạ
Em mở file app.config xem cấu của em có giống như thế này không:
connectionString=”Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\QLBanHang.mdf;Integrated Security=True;User Instance=True”
Nếu giống thì em có thể làm các cách như sau
Cách 1: thay thế |DataDirectory|\QLBanHang.mdf bằng đường dẫn thực đến CSDL của bạn, ví dụ: C:\DB\QLBanHang.mdf
Cách 2: Trong cửa sổ Solution Explorer > chọn vào DataBase QLBanHang.mdf > xuất hiện cửa sổ Property > phần Copy to Output Directory> chọn Copy to newer
E làm được rồi
E cảm ơn thầy ạ
Có 1 lưu ý cho các bạn, ở đoạn thầy viết con.ConnectionString =
Có sử dụng đường dẫn động Application.StartupPath, nhưng khi chạy debug thử thì file .mdf nằm trong thư mục bin/debug chứ ko sử dụng file do mình tạo ra ở thư mục chính của project.
Trong màn hình Visual Studio ở phần Server Explorer thì nó lại hiện file ở thư mục chính của Project vì vậy khi ta chuột phải vào Table chọn Show Table Data sẽ ko thấy dữ liệu mình vừa thêm vào đâu cả, vì thực chất nó ko thêm vào file đó.
// Khao báo đối Tượng connection
SqlConnection con = new SqlConnection();
con.ConnectionString = @”Data Source=.\SQLEXPRESS;AttachDbFilename=D:\web\BaiTapLon\BaiTapLon\QuanLySach.mdf;Integrated Security=True;User Instance=True”;
con.Open();
// Viết câu lệnh truy vấn
String sql = “SELECT * FROM tblMatHang”;
DataSet ds = new DataSet();
SqlDataAdapter dap = new SqlDataAdapter(sql, con);
dap.Fill(ds);
//Gắn Dữ Liệu Lên datagrid
dgvMatHang.DataSource = ds.Tables[0];
dgv.refresh();
}
thầy ơi lỗi báo k có dvg.MatHang cái dvgMatHang tạo ở đâu thế ạ
dvgMatHang chính là control DataGridView để hiển thị thông tin các sản phẩm. Em kéo control này vào form của em rồi đổi Name thành tên dgvMatHang thôi.
Chào thầy! cảm ơn thầy đã tạo ra hướng dẫn mà em đang cần
1/ em đã làm như được hướng dẫn tuy nhiên ở phần Solution explorer không hiển thị như giao diện của thầy (em dùng visual studio 2017, Solusion Explorer không có phần QLBanHangDataSet.xsd).
2/ Sau khi tạo bảng chương trình yêu câu lưu ở định dạng xxx.sql, ở mục server explorer\ table không thấy bảng vừa tạo mặc dù file xxx.sql lưu cùng 1 đường dẫn.
1. Mỗi phiên bản có thể cách hiển thị ở cửa sổ Solution Explorer khác nhau, file này có thể bị ẩn ở phiên bản VS 2017. Em có thể kiểm tra trực tiếp trong thư mục chứa Project của em xem có file này không
2. Em làm theo đúng video hướng dẫn cách tạo database. Nếu không làm được, em cần kiểm tra xem phiên bản của em đã tích hợp SQL Server, nếu chưa có em cần cài tải về cài thêm. Xem thêm: https://www.microsoft.com/en-us/sql-server/sql-server-editions-express
Chào Thầy.
Trường hợp e tao sẳn các bảng dạng *.dbf (lưu sẳn ở 1 thư mục mặt định). việc kết nối file sẽ như thế nào hả thầy.có thể Kết nối bằng dialog để open 1 cái path. Mong thầy chỉ giúp
Có thể làm được, khi em mở dialog ra và lấy đường dẫn đến file *.mdf của em.
Ví dụ như đoạn code dưới:
void showData(string path)
{
String strConnection = @”Data Source=.\SQLEXPRESS;
AttachDbFilename=” + path + “;” +
“Integrated Security=True;” +
“Connect Timeout=30;” +
“User Instance=False”;
SqlConnection con = new SqlConnection(strConnection);
…………
}
Biến path em có thể lấy từ dialog và truyền vào showData(path).
Thưa thầy! EM đang dùng bản Visual Studio 2010! Tạo Database hư trên nhưng đến bước Add new table thì nó hiễn Thông báo là ” This server version is not supported. Only Servers up to MS SQL server 2008 are supported” Em phải khắc phục như thế nào ạ??
Em tải bản SQL Server 2018 rồi cài vào máy em nhé.
Xem một số bản SQL Server 2018:
https://timoday.edu.vn/huong-dan-cai-dat-va-su-dung-sql-server-2008-va-northwind-database/
Em cảm ơn Thầy nhiều ạ
Thưa thầy!
Sai ở chỗ cmd.ExecuteNonQuery(); là lõi ở đâu ạ
Em đưa chuột qua dòng lỗi, sẽ có mô tả lỗi hoặc vào cửa sổ View > Error List.
Em cảm ơn thầy ạ!
Thưa thầy, Em bị lỗi ở
dap.Fill(ds);
Nó báo lỗi này thì phải làm sao ạ?
instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)’
thưa thầy làm sao để phần hiện dữ liệu của datagritview tự động điều chỉnh độ rộng phù hợp vs cửa sổ khi mở rộng ra mà k bị lơ lửng ạ.
em cảm ơn ạ.
Bạn có thể viết code trong sự kiện DataGridView1_DataSourceChanged
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
Em tham khảo thêm các phương án khác ở đây https://stackoverflow.com/questions/1025670/how-do-you-automatically-resize-columns-in-a-datagridview-control-and-allow-the
dạ em cảm ơn thầy ạ
thay co the huong dan em xoa 1 day cai list da chon trong DataGridView , va xoas no trong csdl luon a
Em làm theo bài này:
https://foxlearn.com/articles/delete-multiple-rows-from-datagridview-based-on-checkbox-selection-in-csharp-190.html
thưa thầy, làm sao có thể sử dụng hàm mà trả giá trị bảng trong C# được ạ
Ví dụ sau viết hàm trả về một Datatable
public DataTable GetDataToTable(string sql)
{
SqlDataAdapter dap = new SqlDataAdapter(sql, Con); //Định nghĩa đối tượng thuộc lớp SqlDataAdapter
//Khai báo đối tượng table thuộc lớp DataTable
DataTable table = new DataTable();
dap.Fill(table); //Đổ kết quả từ câu lệnh sql vào table
return table;
}
Xem thêm: https://timoday.edu.vn/xay-dung-chuong-trinh-quan-ly-ban-hang-bang-c/#41_Lop_Functions
private void cmbMS_SelectedIndexChanged(object sender, EventArgs e)
{
cmbNgayKeDon.Items.Clear();
string t=cmbMS.Text.Trim();
string sQuerycmbNgay = “select DISTINCT hdt.mabn, ngaysudung from HoaDonThuoc hdt”;
sQuerycmbNgay += “where mabn='”+ cmbMS.SelectedValue +”‘”;
daQLNg = new SqlDataAdapter(sQuerycmbNgay, conn);
daQLNg.Fill(ds, “tblNgay”);
cmbNgayKeDon.DataSource = ds.Tables[“tblNgay”];
cmbNgayKeDon.DisplayMember = “ngaysudung”;
cmbNgayKeDon.ValueMember = “ngaysusung”;
}
Em muốn khi thay đổi dữ liệu ở combobox cmbMS thì dữ liệu trong combobox cmbNgayKeDon thay đổi theo. Code không báo lỗi nhưng em chạy thì cmbNgayKeDon không hiển thị giá trị. Nhờ thầy chỉ giúp.
chào thầy ạ! Em có khó khăn cần giúp ạ. Hiện e có 1 bảng dl lớp(có tổng số ngày học -songay, ngày bđ- ngaybd(dd,mm,yyyy), ngày kt – ngaykt), em muốn dùng thuật toán tham lam để sắp lớp dựa trên tỏng số ngày học, khóa ngắn ngày sắp trc, em ko bt truy vấn sao bên C#, mong thầy giúp ạ
Thầy ơi em chạy được rồi nhưng khi bấm thêm thì nó lại thông báo lỗi ở cmd.ExecuteNonQuery(); ạ
Em cho mình chi tiết thông báo lỗi
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=Conversion failed when converting date and/or time from character string.
Source=.Net SqlClient Data Provider
StackTrace:
Em cũng bi lỗi giống bạn Đăng Quang, nhờ thầy sữa dùm lỗi này.
Lỗi của em là do chuyển đổi dữ liệu từ chuỗi sang dữ liệu ngày tháng của em bị lỗi. Em có thể khắc phục bằng cách sử dụng Stored Procedure viết ở phần dưới.