Cách cập nhật dữ liệu đồng thời vào Database và DataGirdView

Cách cập nhật dữ liệu đồng thời vào Database và DataGirdView

Khi thao tác với cơ sở dữ liệu và DataGridView, chắc bạn đã từng gặp thao tác thêm, sửa, xóa dữ liệu từ Database rồi Load lại lên DataGirdView. Đó là cách thông thường bạn hay làm, đơn giản và dễ viết cho những bạn mới tiếp xúc với ADO.NET. Tuy nhiên, nếu bạn để ý với dữ liệu lớn dần (vài trăm, vài triệu bản ghi) thì việc Load lại dữ liệu từ DB lên không còn hợp lý nữa. Vậy bài viết này, tôi giới thiệu với các bạn “Cách cập nhật dữ liệu đồng thời vào Database và DataGirdView mà không Load lại dữ liệu”.

Vậy giải pháp cho vấn đề này là gì? Đó là:

1.  Hãy thêm, sửa, xóa vào CSDL liệu trước (Có đảm bảo ràng buộc dữ liệu). Nếu thành công thì mới sang mục 2

2. Cập nhật những thay đổi ở buốc 1 lên DataGirdView thông qua đối tượng BindingSource. Vì không thể Add trực tiếp 1 hàng vào DataGridView khi đã gán DataSource cho nó.

Hướng dẫn sau sẽ giúp bạn hiểu rõ hơn vấn đề trên. Trong bài viết này, tôi vẫn sử dụng CSDL SQL Server quen thuộc trong các bài viết trước, có tên HRM, có 1 bảng đơn giản là: Departments.

Bước 1: Thiết kế CSDL với bảng Departments như dưới đây

Lưu ý: Trường DepartmentID ở đây tôi thiết lập là khóa chính, tự động tăng

Bước 2: Bây giờ bạn cần thiết kế giao diện như sau:

Cách cập nhật dữ liệu đồng thời vào Database và DataGirdView

Cách thiết kế và gán ràng buộc dữ liệu với DataGridView tôi đã trình bày trong bài viết trước. Trong ví dụ này bạn ràng buộc dữ liệu với 2 trường: DepartmentID, DepartmentName, Description. Tuy nhiên cột Mã phòng ban của bạn sẽ ẩn đi bằng cách cho thuộc tính Visible của cột đó = False. Tại sao lại ẩn đi? Nhằm trong suốt với người dùng, đây là trường tự động tăng nên người dùng không cần nhập, không cần quan tâm, nhưng lại là trường mà người lập trình cần thiết kế để thuận tiện trong thao tác cập nhật.

Sau đó bạn bổ sung vào giao diện 2 ô TextBox (txtName và txtDescripton), 3 Button: btnAdd, btnUpdate, btnDelete.

Ta được giao diện như hình sau:

Bước 3: Lập trình hiển thị dữ liệu lên DataGridView

Đầu tiên bạn hãy khai báo và khởi tạo đối tượng Connection. Thông thường bạn hay viết một hàm LoadData() dùng để load dữ liệu lên DataGridView, tuy nhiên trong bài viết này không cần nữa, vì ta không dùng lại nó. Bạn hãy viết Code hiển thị dữ liệu ngay trong Load Form.

Viết code như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string strConn = @"Server=.\SQLEXPRESS; Database=HRM; Integrated Security=True";
        SqlConnection conn;
  
        // Khai báo và khởi tạo đối tượng ràng buộc dữ liệu
        BindingSource bs = new BindingSource();
 
        private void frmDepartment_Load(object sender, EventArgs e)
        {
            conn = new SqlConnection(strConn);  
 
            // Lấy về dữ liệu dạng DataTable
            SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Departments", conn);
            DataTable dt = new DataTable();
            da.Fill(dt);
 
            // Ràng buộc dữ liệu vào BindingSource
            bs.DataSource = dt;
 
            // Gán nguồn dữ liệu cho DataGridView
            dgvDeparts.DataSource = bs;
        }

Khi viết xong đoạn lệnh trên, bạn chạy lên thì kết quả  có thể đã hiển thị nhưng cột STT vẫn trống vì không có ràng buộc với trường này. Bởi vậy bạn hãy viết trong sự kiện RowPrePaint của điều khiển DataGridView như sau:

1
2
3
4
private void dgvDeparts_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
     {
         dgvDeparts.Rows[e.RowIndex].Cells["clNo"].Value = e.RowIndex + 1;
     }

Lúc này cột số thứ tự của bạn sẽ điền số tự động như mong muốn.

Hãy chuyển sang bước 4.

Bước 4: Hiển thị dữ liệu lên TextBox tương ứng khi chọn 1 dòng trong DataGridView

1
2
3
4
5
6
7
8
private void dgvDeparts_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
    {
        txtName.Text = Convert.ToString(dgvDeparts.CurrentRow.Cells["clName"].Value);
        txtDescription.Text = Convert.ToString(dgvDeparts.CurrentRow.Cells["clDescription"].Value);
    }
}

Bước 5: Thực hiện thêm mới một phòng ban có thể dùng thủ tục hoặc lệnh, hay hàm nào đó trong Mô hình 3 lớp. Giả sử ở đây tôi dùng lệnh, cho đơn giản.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void btnAdd_Click(object sender, EventArgs e)
        {
            if (conn.State == ConnectionState.Closed)
                conn.Open();
 
            SqlCommand cmd = new SqlCommand("INSERT INTO Departments VALUES(N'"+txtName.Text+"', N'"+txtDescription.Text+"')",conn);
            int count = cmd.ExecuteNonQuery();
 
            if (count > 0)
            {
                DataTable dt = (DataTable)bs.DataSource;
                DataRow row = dt.NewRow();
                row["DepartmentName"] = txtName.Text;
                row["Description"] = txtDescription.Text;
                dt.Rows.Add(row);
 
                MessageBox.Show("Thêm mới thành công");
 
                //LoadData();   // Không gọi hàm này nữa
 
 
            }
            else MessageBox.Show("Không thể thêm mới");
        }

Bạn có thể chạy chương trình và thử nghiệm! Bạn sẽ cảm nhận thấy sự nhẹ nhàng khi không phải load lại 1 khối lượng lớn dữ liệu.

Ở đây bạn cần phải hiểu rằng, khi bạn thay đổi dữ liệu nguồn của BindingSource thì nó sẽ tự động cập nhật lại trên DataGridView.

Bước 6: Tương tự cho việc thực thi các thủ tục sửa và xóa như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
   private void btnUpdate_Click(object sender, EventArgs e)
        {
if (conn.State == ConnectionState.Closed)
                conn.Open();
 
            int id = (int)dgvDeparts.CurrentRow.Cells["clID"].Value;
            SqlCommand cmd = new SqlCommand("UPDATE Departments Set DepartmentName = N'" + txtName.Text + "', Description = N'" + txtDescription.Text + "' WHERE DepartmentID = "+id, conn);
         
            int count = cmd.ExecuteNonQuery();
 
            if (count > 0)
            {
                DataRowView row = (DataRowView)bs.Current; // Hàng chọn hiện thời
                row["DepartmentName"] = txtName.Text;
                row["Description"] = txtDescription.Text;
                bs.ResetCurrentItem();
 
                MessageBox.Show("Sửa thành công!");
                // LoadData();
 
            }
            else MessageBox.Show("Không sửa được!");
 
        }
 
 
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Bạn có chắc chắn muôn xóa bản ghi đang chọn không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                if (conn.State == ConnectionState.Closed)
                    conn.Open();
 
                int id = (int)dgvDeparts.CurrentRow.Cells["clID"].Value;
                SqlCommand cmd = new SqlCommand("Delete Departments WHERE DepartmentID = " + id, conn);
 
                int count = cmd.ExecuteNonQuery();
 
                if (count > 0)
                {
                    DataRowView row = (DataRowView)bs.Current; // Hàng chọn hiện thời
                    row.Delete();
 
                    MessageBox.Show("Xóa thành công!");
                    // LoadData();
 
 
                }
                else MessageBox.Show("Không thể xóa bản ghi hiện thời!");
            }
        }

Bạn có thể làm được như trên! Hãy thử nhé!

Hãy làm theo cách này khi bạn muốn tăng hiệu suất của ứng dụng. Hãy ánh xạ nó vào dự án của bạn, nếu là Mô hình 3 lớp, chỉ cần thay DataTable = List đối tượng . Ví dụ trong bài trên tôi có thể dùng List<Department> để thay thế cho DataTable. Bạn làm ví dụ đơn giản này trước rồi hãy ánh xạ nhé!

Chúc bạn thành công!

Bạn thấy bài viết này như thế nào?: 
Average: 10 (7 votes)
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Android

Tương lai của Adobe và sự thất bại của Flash

Một kịch bản khó có thể tưởng tượng là Adobe đã từ bỏ cung cấp Flash Player dành cho các thiết bị di động. Vừa qua, Adobe đã lặng lẽ gỡ bỏ hoàn toàn ứng dụng Flash trên Google Play Store. Đây là một dấu hiệu khẳng định Flash đã thừa nhận thất bại và chính thức bị “khai tử”.

Hướng dẫn tạo 1 userr mới - SSH user on Centos

Hướng dẫn tạo 1 userr mới - SSH user on Centos

You can also grant root permissions to this username by using sudo for all commands:

Người dùng Facebook ở Đức được phép dùng tên giả

Người dùng Facebook ở Đức được phép dùng tên giả

Bất kỳ công ty nào hoạt động tại Đức đều sẽ phải tuân theo bộ luật của đất nước này - ủy ban luật pháp tại Hamburg, Đức phán quyết

Công ty diệt chuột T&C

 

Diet con trung