ADO.NET – Cơ bản về DataSet (Part 1/2): Cấu trúc của DataSet và DataTable

DataSet là một đối tượng có thể chứa nhiều DataTable cùng với mối liên hệ giữa chúng (relationship) và kể các ràng buộc (constraint) được lưu hoàn toàn trong bộ nhớ để làm việc offline. Qua bài viết này, bạn có thể hiểu cấu trúc của DataSet, DataTable cũng như nạp dữ liệu, tạo relation, constraint và thao tác dữ liệu trên các đối tượng dữ liệu này.


Nội dung bài viết:

Cấu trúc của DataSet và DataTable

Nạp dữ liệu vào DataSet từ database

Tạo dữ liệu động cho DataTable

Cấu trúc của DataSet và DataTable

Namespace: System.Data

Một DataSet tương tự như một tập tin database vật lý hoàn chỉnh nhưng được lưu trong bộ nhớ. DataSet bao gồm các DataTable, DataTable bao gồm các DataColumn, DataRow, các constraint được minh họa như hình dưới:

Các property của DataSet và DataTable dùng để lưu trữ các collection theo hình minh họa trên.

DataSet:

Type Name Description
DataTableCollection Tables Gets the collection of tables contained in the System.Data.DataSet
DataRelationCollection Relations Get the collection of relations that link tables and allow navigation from parent tables to child tables.

DataTable:

Type Name Description
DataColumnCollection Columns Gets the collection of columns that belong to this table.
DataRowCollection Rows Gets the collection of rows that belong to this table.
ConstraintCollection Constraints Gets the collection of constraints maintained by this table.

Nạp dữ liệu vào DataTable và DataSet

Để thực hiện các ví dụ với DataSet và DataTable, tôi đã chuẩn bị một database đơn giản trên SQL Server gồm hai bảng. Để thực hiện được bước này, yêu cầu bạn phải có sẵn kiến thức về kết nối database trong ADO.Net. Bạn có thể xem tại link sau:

Connecting to a Data Source (ADO.NET)

Dữ liệu minh họa

Table Groups:

GroupID GroupName
1 Member
2 Moderator
3 Super Moderator
4 Admin

 

Table Users:

UserID

UserName

GroupID

1 Adon

1

2 Akuma

2

3 Balrog

1

4 Bison

1

5 Blanka

3

6 Cammy

1

7 ChunLi

1

8 Cody

4

9 Dan

1

10 DeeJay

1

 

Nạp dữ liệu vào DataSet từ database

Phương thức sau sẽ kết nối đến database SQL Server, sau đó nạp hai table User và Group vào DataSet. Khi làm ví dụ, bạn hãy sửa chuỗi kết nối theo máy bạn và tạo các table tương ứng.

private static DataSet LoadData()
{
    var conn = new SqlConnection(
        "Server=YINYANG\\SQLEXPRESS;Database=YinYangDB;Trusted_Connection=true");

    conn.Open();

    var cmd = "Select * from Users";
    var dataAdapter = new SqlDataAdapter(cmd, conn);

    var dataSet = new DataSet();

    dataAdapter.Fill(dataSet, "User");

    dataAdapter.SelectCommand.CommandText = "Select * from Groups";
    dataAdapter.Fill(dataSet, "Group");

    conn.Close();

    return dataSet;
}

Phương thức Fill(DataSet) của DataAdapter tự động lấy tên bảng mà bạn đặt trong CommandText để đặt tên cho DataTable, tuy nhiên để chắc chắn tên bảng đúng trong trường hợp có sửa đổi, tôi dùng overload Fill(DataSet,string) để đặt tên lại cho các table.

Thay vì Fill() vào DataSet, bạn có thể dùng Fill(DataTable) để tạo ra một DataTable mới, sau đó thêm vào DataSet:

var table=new DataTable("Group");

dataAdapter.Fill(table);

dataSet.Tables.Add(table);

Một số tên table có thể trùng với từ khóa mà SQL sử dụng (ví dụ: User), mặc dù điều này ít khi xảy ra nhưng bạn có thể đề phòng trước bẳng cách sử dụng quy tắc đặt tên như sử dụng tiền tố, đặt tên theo danh từ số nhiều,…

Ngoài cách nạp dữ liệu từ datatable, bạn cũng có thể tạo dữ liệu động cho DataTable thông qua các collection Columns và Rows. Phần sau sẽ giới thiệu về cách thực hiện này.

Tạo dữ liệu động cho DataTable

Kiểu dữ liệu DataColumn chứa đầy đủ các property cần thiết để bạn tạo ra một mô hình dữ liệu hoàn chỉnh cho DataTable. Ta có thể tạo một column dùng làm ID với chỉ số tự động tăng bắt đầu từ 1, không cho phép null và là duy nhất như sau:

DataColumn col = new DataColumn("ID", typeof(int));

col.AllowDBNull = false;
col.AutoIncrement = true;
col.AutoIncrementSeed = 1;
col.Unique = true;

Các DataColumn cần thiết phải có hai thông tin là tên và kiểu dữ liệu. Khi đã có một DataTable rỗng, công việc thêm các DataColumn vào rất đơn giản. Ví dụ sau tạo một DataTable với tên Persons với ba column là ID, Name và Birthday cùng với kiểu dữ liệu tương ứng là int, string và DateTime:

DataTable table = new DataTable("Persons");

DataColumn col = new DataColumn("ID", typeof(int));

col.AllowDBNull = false;
col.AutoIncrement = true;
col.AutoIncrementSeed = 1;
col.Unique = true;

table.Columns.Add(col);
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Birthday", typeof(DateTime));

DataTable của chúng ta vẫn là rỗng vì chưa có dữ liệu (chỉ có mô hình dữ liệu). Để tạo một DataRow ta cần gọi phương thức DataTable.NewRow(). Phương thức này trả về một DataRow với các ô chứa dữ liệu tương ứng với các cột của DataTable. Công việc thêm dữ liệu cũng rất đơn giản, dựa vào hai overload của DataRowCollection.Add() như bạn thấy dưới đây:

DataRow newRow = table.NewRow();

newRow["ID"] = 1; // remove this line
newRow["Name"] = "Boo";
newRow["Birthday"] = new DateTime(1990,3,4);

table.Rows.Add(newRow);
table.Rows.Add(null, "Bee", new DateTime(1989, 5, 3));

Một đoạn code nhỏ để in ra kết quả:

foreach (DataRow row in table.Rows)
{
    Console.WriteLine("ID={0}, Name={1}, Birthday={2}",
        row["ID"], row["Name"], row["Birthday"]);
}

Output:

ID=1, Name=Boo, Birthday=04/03/1990 12:00:00 AM

ID=2, Name=Bee, Birthday=03/05/1989 12:00:00 AM

Như bạn thấy cột ID tự động tăng, ngay cả khi bạn xóa bỏ dòng gán newRow[“ID”] = 1.

>> Part 2: DataRelation và Constraint

https://yinyangit.wordpress.com

46 thoughts on “ADO.NET – Cơ bản về DataSet (Part 1/2): Cấu trúc của DataSet và DataTable

  1. Hi Yin Yang

    Bạn cho mình hỏi trường hợp mình đã bind data từ 2 tables không có relation có 2 columns cùng tên nhưng giá trị lộn xộn vào 2 DataSet hoặc 2 DataTable, Bây giờ mình muốn so sánh để lấy tên sản phẩm của nó thì làm ntn?

    Ví dụ:
    table A có column SoLuong gồm các giá trị: 2,3,4,6,8,9….
    table B có column SoLuong gồm các giá trị: 9,3,4,5,3,9…. & column TenSP.

    Mình muốn dựa trên column SoLuong nếu SoLuong ở table A được tìm thấy ở table B thì xuất ra tên sản phẩm tương ứng thì mình phải code ntn?

    Trả lời
  2. Hi Yin Yang

    Có cách nào sử dụng loop foreach trên DataSet hoặc DataSet ko bạn? Tui sử dụng như thế này nhưng chưa đúng thì phải

    foreach (DataRow dr1 in dt1.Rows) //voi data đã được bind vào dt1 & dt2
    {
    foreach (DataRow dr2 in dt2.Rows)
    {
    if (dr1[“SoLuong”].ToString() != dr2[“SoLuong”].ToString())
    {
    //do something
    }
    else {
    //do something
    }
    }
    }
    Nhờ Yin Yang tư vấn thêm chỗ này với! Thanks!!!

    Trả lời
  3. Yin Yang :

    Bạn dùng foreach như vậy là đúng rồi tuy nhiên không cần thiết phải dùng nó. Bạn chỉ cần dùng property Filter hoặc method Select() của DataView, DataTable là được.

    Dùng property Filter & method Select() ntn nhỉ Yin Yang? Bạn demo giúp với, mình chưa hiểu rõ cách sử dụng nó. Thanks bạn!!!

    Trả lời
  4. Hi Yin Yang

    Bạn cho hỏi trong 01 file .cs của WINFORM tôi chỉ khai báo 01 biến toàn cục cho các đối tượng của ADO.NET như DataSet, SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter; sau đó sử dụng trong toàn bộ file .cs đó. Liệu có gây nên lỗi của chương trình ko bạn & nó có đảm bảo toàn vẹn dữ liệu ko nhỉ?

    Cụ thể với DataSet ở 01 thời điểm A tôi Fill data vào nó 02 tables khác nhau (khi Form Load), ở 01 thời điểm B tôi lại Fill data vào nó 02 tables khác nữa (khi user chọn 01 điều kiện gì đó). Và sau đó ở 01 thời điểm C tôi cần lấy data đã Fill vào DataSet ở thời điểm B để Add data vào DataSet ở thời điểm A, đồng thời lưu vào CSDL luôn.

    Với bài toán này mình đang bí lối đi quá Yin Yang có thể tư vấn giúp được ko? Thanks!!!

    Trả lời
  5. Cụ thể với DataSet ở 01 thời điểm A tôi Fill data vào nó 02 tables khác nhau (khi Form Load), ở 01 thời điểm B tôi lại Fill data vào nó 02 tables khác nữa (khi user chọn 01 điều kiện gì đó). Và sau đó ở 01 thời điểm C tôi cần lấy data đã Fill vào DataSet ở thời điểm B để Add data vào DataSet ở thời điểm A, đồng thời lưu vào CSDL luôn.

    Ví dụ: dâtaset1 có table A & B, dataset2 có table C & D trong đó A & C có cấu trúc colums giống nhau, B & D cũng vậy. Data của C & D là n record.
    Table A & B được Fill data ở event FormLoad lấy từ CSDL1
    Table C & D được Fill data ở event User chọn 01 điều kiện nào đó lấy từ CSDL2

    Yin Yang chỉ tôi cách làm thế nào để gán dữ liệu từ C vào A & D vào B, để sau đó tôi Insert data từ A & B vào A & B trong CSDL, tôi sử dụng phương pháp Disconnected Data – DataSet & SqlDataAdapter.

    Trả lời
  6. Việc bạn fill data vào thời điểm nào hay bao nhiêu không quan trọng. Như vậy thì DataSet của bạn có thể chứa 4 table. Bạn chỉ cần quan tâm việc gán dữ liệu từ table này sang table kia. Mình không rõ bạn dùng từ “gán” là muốn nói đến công việc nào. Nhưng sau khi gán thì bạn có thể update vào csdl từng table riêng lẻ, ko nhất thiết là phải cả 4 table.

    Trả lời
  7. Ok mình đã xử lý được phần này nhưng còn đang vướng ở chỗ, vì 2 tables có quan hệ cha – con, & cũng cần lấy data từ 2 tables đó nên khi truy vấn tôi đã join nó lại nên khi Fill lại lên DataSet 2 tables nhưng thật chất chỉ có 1 table vì chúng same.

    Trường hợp 1 cha 1 con thì Insert bình thường nhưng trường hợp 1 cha nhiều con thì bị ném lỗi trùng khóa chính ở bảng cha & ko thực hiện insert được…Yin Yang có thể chỉ mình thuật toán để khắc phục vấn đề này được ko? Thanks!!!

    Trả lời
  8. Hi Yang

    Cách Insert của mình như sau:
    Đầu tiên mình Fill 2 tables A & B từ CSDL 1 vào table AB (đương nhiên trong AB đã có data của A & B), sau đó mình dùng loop để gán data vào 2 tables D & E của CSDL 2 như sau:

    foreach(DataRow drAB in ds.Tables[“AB”].Rows){
    DataRow drD = ds.Tables[“D”].NewRow();
    drD[“NameColumnOf_D”]=dr[“AB”];….. cho đến hết các colums của table D cần insert data vào, rồi Add các drD vào table D;

    sau đó tiếp tục
    DataRow drE = ds.Tables[“E”].NewRow();
    drE[“NameColumnOf_E”]=dr[“AB”];….. cho đến hết các colums của table E cần insert data vào, ,rồi Add các drE vào table E
    }

    Sau khi loop foreach chạy hết thì mình gọi hàm Insert theo phương pháp Disconnected Data – DataSet & SqlDataAdapter.

    Do Fill data từ 2 tables có sử dụng Join table nên trường hợp 1 cha nhiều con nên sẽ xuất hiện nhiều hàng có trùng khóa chính. Và cả trường hợp chỉ có 1 cha & 1 con.

    Trường hợp 1 cha 1 con thì Insert bình thường nhưng trường hợp 1 cha nhiều con thì bị ném lỗi trùng khóa chính ở bảng cha & ko thực hiện insert được…Yin Yang có thể chỉ mình thuật toán để khắc phục vấn đề này được ko? Thanks!!!

    Trả lời
  9. Nói thêm cho rõ phần trình bày trên:

    Table A có IDA là khóa chính (cha), table B nhận IDA làm khóa ngoại (con). Khi Fill lên table AB mình đã đổi tên IDA thành IDD để giống với khóa chính của table D.

    Với D là table cha có IDD là khóa chính, E là table con nhận IDD làm khóa ngoại nha Yin Yang. Mình phải code ntn để vẫn có thể Insert vào D & E trong cả trường hợp table AB có 1 cha 1 con & trường hợp table AB có 1 cha nhiều con mà không bị lỗi trùng khóa chính.

    Trả lời
  10. Hi Yin Yang

    Bạn cho tôi hỏi đoạn code này

    private static DataSet LoadData()
    {
    var conn = new SqlConnection(
    “Server=YINYANG\\SQLEXPRESS;Database=YinYangDB;Trusted_Connection=true”);

    conn.Open();

    var cmd = “Select * from Users”;
    var dataAdapter = new SqlDataAdapter(cmd, conn);

    var dataSet = new DataSet();

    dataAdapter.Fill(dataSet, “User”);

    dataAdapter.SelectCommand.CommandText = “Select * from Groups”;
    dataAdapter.Fill(dataSet, “Group”);

    conn.Close();

    return dataSet;
    }

    Nếu tôi sử dụng store procedure thì tôi phải code lại ntn cho đúng? Thanks!!!

    Trả lời
  11. Link bạn cung cấp ở trên là dùng stored procedure với SqlCommand, mình đã xem trong toàn bộ bài ở đó ko có nói đến vấn đề mình đang muốn hỏi, cái mình muốn hỏi là dùng DataSet – SqlDataAdapter – Stored Procedure kia mà. Method LoadData bạn dùng query string, cái mình muốn hỏi là trường hợp ko dùng query string mà dùng stored procedure thì code lại ntn cho đúng?

    Trả lời
  12. Mình thấy hơi lạ là bạn lại tách SqlCommand ra khỏi SqlDataAdapter. Điểm khác biệt giữa các lấy dữ liệu từ câu query và stored procedure chỉ khác nhau ở cách thiết lập SqlCommand thôi. Ko liên quan gì tới SqlDataAdapter. Bạn chỉ cần thiết lập SqlCommand như trong link mình giới thiệu rồi truy vấn dữ liệu bình thường.

    Trả lời
  13. Trời bạn nói tui tách SqlCommand ra khỏi SqlDataAdapter là sao ta??? Ko hiểu bạn nói gì luôn. Tôi có tách gì đâu, bạn xem lại toàn bộ comment đi nha, tôi ko hề đề cập đến việc tách SqlCommand & SqlDataAdapter.

    Bời vì tôi thấy dòng này

    dataAdapter.SelectCommand.CommandText = “Select * from Groups”;

    Ở demo bên trên nên tôi muốn hỏi thêm cách dùng sp với SqlDataAdapter mà thôi.

    Trả lời
  14. Hi Yin Yang

    Nếu dùng SqlCommand để thực thi stored procedure, vậy làm sao Fill dữ liệu vào DataSet hoặc DataTable, tôi chưa thấy Lesson nào của bạn nói về vấn đề này? Làm sao đây ta…!!!

    dataAdapter.SelectCommand.CommandText => tôi thấy có diễn giải là Get or Set the T- SQL statement, table name or stored procedure to execute at data source & tôi có thử dùng thì có thể gọi stored procedure bằng cách dataAdapter.SelectCommand.CommandText = sp_Name ;rùi Fill dữ liệu vào DataSet được.

    Tôi thấy SqlDataAdapter nhận luôn cả dòng lệnh này: dataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure; nhưng diễn giải lại trỏ đến cho SqlCommand là sao ta??? Nên chưa thử phần này!!!

    Yin Yang có thêm demo nhé!!!

    Trả lời
  15. Hi Yin Yang, cho mình hỏi. t làm việc với 2 tables trong database. Đã xog phần hiển thị lên datagridview bằng cách join 2 bảng lại rồi đưa vào cùng 1 datatable, giờ đến phần thêm xóa sửa update ngược trở về database. Cách t làm như sau: viết transaction cho insert dữ liệu đối với từng bảng, Sau đó mình select lại dữ liệu trong datatable bằng cách gọi hàm làm những việc sau:
    var cmd = “Select * from A INNER JOIN B ON A.att = B.att”;
    var dataAdapter = new SqlDataAdapter(cmd, conn);
    var table=new DataTable();
    dataAdapter.Fill(table); //fill lại dữ liệu vào datatable cũ
    dataSet.Tables.Add(table); //add lại dữ liệu vào dataSet, trc đó đã add vào dataSet cái datatable này rồi, ko biết làm thế này có đúng chưa??

    bài t làm bị lỗi không biết sửa làm sao, mới học nên chưa biết nhiều lắm, cậu chỉ cho mình tỏ đi.

    Trả lời
  16. mình đã thử sửa lại theo hướng dẫn của YinYang tuy nhiên mình nhận dc lỗi là: “Procedure or function ‘sp_addPhieuXuat’ expects parameter ‘@SoPX’, which was not supplied.” mặc dù đã cung cấp đủ parameters cho stored proc.
    code cho btnSave:
    private void btnSave_Click(object sender, EventArgs e)
    {
    int pos = dgrvPhieuXuat.CurrentRow.Index;
    bmPX.AddNew();
    DataRow dr = dtPhieuXuat.NewRow();
    dr[“SOPX”] = dgrvPhieuXuat.Rows[pos].Cells[“MaPX”].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“MaPX”].Value);
    dr[“MAVTU”] = dgrvPhieuXuat.Rows[pos].Cells[1].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“MaVT”].Value);
    dr[“TENKH”] = dgrvPhieuXuat.Rows[pos].Cells[2].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“TenKH”].Value);
    dr[“NGAYXUAT”] = dgrvPhieuXuat.Rows[pos].Cells[3].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“NgayXuat”].Value);
    dr[“SLXUAT”] = dgrvPhieuXuat.Rows[pos].Cells[4].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“SLGXUAT”].Value);
    dr[“DGXUAT”] = dgrvPhieuXuat.Rows[pos].Cells[5].Value;
    Console.WriteLine(dgrvPhieuXuat.Rows[pos].Cells[“DONGIA”].Value);
    dtPhieuXuat.Rows.Add(dr);

    transaction = con.BeginTransaction();
    cm = con.CreateCommand();
    cm.CommandText = “sp_addPhieuXuat”;
    cm.CommandType = CommandType.StoredProcedure;

    cm.Parameters.Add(“@SoPX”, SqlDbType.Char, 4, “SOPX”);
    cm.Parameters.Add(“@MaVT”, SqlDbType.Char, 4, “MAVTU”);
    cm.Parameters.Add(“@TenKH”, SqlDbType.NVarChar, 50, “TENKH”);
    cm.Parameters.Add(“@NgayXuat”, SqlDbType.DateTime, 20, “NGAYXUAT”);
    cm.Parameters.Add(“@SLXuat”, SqlDbType.Int, 5, “SLXUAT”);
    cm.Parameters.Add(“@DonGia”, SqlDbType.Money, 30, “DGXUAT”);
    cm.Connection = con;
    cm.Transaction = transaction;
    try
    {
    cm.ExecuteNonQuery();
    transaction.Commit();
    }
    catch (System.Exception ex) //đã bắt catch ở đây!!!!!!!!!!!
    {
    MessageBox.Show(“Lỗi: ” + ex.Message, “THÔNG TIN LỖI”, MessageBoxButtons.OK, MessageBoxIcon.Error);
    transaction.Rollback(); //roll back nếu dữ liệu ko insert dc vào db
    }

    bmPX.EndCurrentEdit();
    }
    Mình đã thử in ra Console các giá trị trong datagridview thì nhận dc đúng như lúc nhập vào. Vậy đáng lẽ ra trong datarow fai có dr[“SOPX”] chứ ta? Project mh attach link ở trên. YinYang paste đoạn này vào test thử giùm mh với.

    Trả lời
  17. YinYang ơi, bây giờ mình làm nút lưu cho trên 1 bảng khi add 1 row vào datatable cũng bị lỗi cột khóa chính ko cho phép null nữa. Mặc dù mh get lấy giá trị từ datagridview đưa vào datarow rồi mà, sao kì vậy YinYang? cậu giải thích cho mình với. Có vẻ như lỗi này giống lỗi ở cái lưu row nhiều bảng ở trên nhỉ? mh cho thao tác trục tiếp trên datagridview luôn, ko thông qua các control nhu textbox….
    code nút lưu 1 nhà cung cấp mới:
    private void btnSave_Click(object sender, EventArgs e)
    {
    bmNCC.AddNew();
    int pos = dgrvNCC.CurrentRow.Index;
    DataRow dr = dtNCC.NewRow();
    dr[“MANHACC”] = dgrvNCC.Rows[pos].Cells[“MaNCC”].Value;
    dr[“TENNHACC”] = dgrvNCC.Rows[pos].Cells[“TENNCC”].Value;
    dr[“DIACHI”] = dgrvNCC.Rows[pos].Cells[“DiaChi”].Value;
    dr[“DIENTHOAI”] = dgrvNCC.Rows[pos].Cells[“DienThoai”].Value;
    dtNCC.Rows.Add(dr); //báo lỗi ở đây nè, “Column ‘MANHACC’ does not allow nulls.”
    bmNCC.EndCurrentEdit();
    da.Update(dtNCC);
    }
    giúp mh gấp Yin Yang oi!

    Trả lời
  18. Hi YinYang, link project: http://www.mediafire.com/?u8bmid7e9sd72f8
    trong project có 3 form: updNCC, updVATTU là thực hiện thêm xóa sửa tác động đến 1 table trong database, hiện tại thì mình đã thêm được, nhưng xóa và sửa thì lại báo lỗi là “do mh ko cung cấp parameter cho cái khóa chính” 😐
    Form nữa là thực hiện thêm xóa sửa trên 2 tables PXUAT và CTPXUAT, mh đã đổi lại thành file test.cs, viết toàn bộ phần kết nối hay fill dữ liệu vào DataTable riêng trong file này, chứ ko dùng thêm class DBConn_FillData.cs.
    Đối với form “test.cs” này thì chỉ mới insert thôi đã lỗi rồi, nên mh chưa đính code cho nút xóa và sửa.
    Mình có kèm file csdl là db.sql, trong đó có các bảng cũng như diagrams và stored proc mh viết để dùng cho việc cập nhật trên nhiều bảng. Up luôn để bạn tiện theo dõi. Test giùm mh nhe!

    Trả lời
      • hi Yin Yang, project mh gửi cho bạn là gồm những form mình thắc mắc đó. Những form còn lại là làm phần show dữ liệu lên gridcontrol dùng devexpress thôi, không liên quan nên mình ko post cho nhẹ file nén dễ up lên, sorry mạng nhà mh yếu lắm, chứ ko phải ko có thiện ý up project hoàn chỉnh. link mới đây: http://www.mediafire.com/?ydyulrgm7d3aeog. mh mới sửa lại 1 chỗ trong file test.cs, nhưng vẫn chưa insert dc, do lỗi convert từ string sang datetime, mình chưa tìm dc cách khắc phục, bạn test giùm mh nhe.

      • Lý do mình yêu cầu bạn up lại là mình không thể test, debug project bạn được. Nếu không thể up được vậy bạn có thể cung cấp thông tin chi tiết hơn. Form test của bạn mình ko thấy code update hay delete. Còn insert phần format datetime thì có lẽ điều này không phức tạp. Mình hầu như ko làm đến những ứng dụng ADO.NET dạng này nên cũng không thể đọc mà phát hiện được vấn đề ngay được.

  19. Yin Yang có thể cho t cái mail ko? t nhờ bạn gửi project giùm cho Yin Yang. t xóa mấy file rùi vẫn debug dc mà. lúc mở project lên cái nào có ! màu vàng, Yin Yang cứ xóa hết đi rồi debug giùm t nhé. còn ko tiện thì Yin Yang cho t cái mail. t kẹt cái này cả mấy tuần rồi Google search thử bao nhiêu cách ko ra dc 😦 Mong Yin Yang xem giùm

    Trả lời
  20. Sorry bạn, bữa nói bạn gửi project mà mấy hôm nay về quê, không có lên mạng. Để tối nay mình test bài bạn. Mình có mở project ra xem, nếu bạn xóa những file class, bạn nên xóa trong Visual Studio chứ không nên xóa file trực tiếp trên ổ cứng. Và bài của bạn có sử dụng Dev Express, mình đã thử xóa nó luôn rồi mới chạy lên được.
    Bạn có thể gửi mail cho mình: minhtam.seta@gmail.com để liên lạc

    Trả lời
  21. Pingback: I'm a Post Thief

  22. {
    string ngaytra = dtngaytra.Value.ToString();
    string ngayhentra = cbongayhentra.Text.ToString();
    int ngay1 = Convert.ToInt32(ngaytra.Substring(3, 2));
    int thang1 = Convert.ToInt32(ngaytra.Substring(0, 2));
    int nam1 = Convert.ToInt32(ngaytra.Substring(6, 4));
    int ngay2 = Convert.ToInt32(ngayhentra.Substring(3, 2));
    int thang2 = Convert.ToInt32(ngayhentra.Substring(0, 2));
    int nam2 = Convert.ToInt32(ngayhentra.Substring(6, 4));

    DateTime ngaytraCT = new DateTime(ngay1,thang1,nam1);
    DateTime ngayhenTra = new DateTime(ngay2,thang2,nam2);
    if (ngaytraCT <= ngayhenTra)
    buMT.Deletemt(mt);
    textBox1.Text = "Đã trả sách" + "số tiền phạt 0vđ";
    }

    Trả lời

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s