Thứ Hai, 5 tháng 8, 2013

Các cố gắng thay đổi DataSet -Lập trình CSDL trong C#

Sau khi soạn thạo dữ liệu trong một DataSet, cũng có những lúc cần phải thay đổi nó. Một ví dụ khá phổ biến đó là chọn dữ liệu từ một cơ sở dữ liệu, biểu diễ nó cho người dùng, và cập nhật cho cơ sở dữ liệu.

Cập nhật với các Data Adapter

Một SqlDataAdapter có thể bao gồm SelectCommand, một InsertCommand, UpdateCommand,DeleteCommand. Giống như tên gọi, những đối tượng này là những thể hiện của SqlCommand (hoặc OleDbCommand dùng cho OleDbDataAdapter), vì vậy những câu lệnh này có thể chuyển thành SQL hoặc một stored procedure.
Trong ví dụ này, tôi đã khôi phục lại các mã stored procedure từ phần Calling Stored Procedures để chèn, cập nhật, và xóa các mẫu tin Region. Mã có sẵn trong thư mục 12_DataAdapter2.

Chèn một dòng mới

Có hai cách để thêm một dòng mới vào một DataTable. Cách thứ nhât là gọi phương thức NewRow, để trả về một dòng trống sau đó định vị và thêm vào tập Rows như sau:
DataRow r = ds.Tables["Region"].NewRow();
r["RegionID"]=999;
r["RegionDescription"]="North West";
ds.Tables["Region"].Rows.Add(r);
Cách thứ hai để thêm một dòng mới là truyền một mảng dữ liệu vào phương thức Rows.Add() giống như sau:
DataRow r = ds.Tables["Region"].Rows.Add 
             (new object [] { 999 , "North West" });
Mỗi dòng trong DataTable sẽ cài RowStateAdded. Ví dụ sẽ xổ ra các mẫu tin trước khi nó thay đổi được cập nhật cho dữ liệu, vì vậy sau khi thêm các dòng sau vào DataTable, các dòng sẽ giống như sau. Chú ý rằng cột bên phải là trạng thái dòng.
New row pending inserting into database
  1   Eastern                                            Unchanged
  2   Western                                            Unchanged
  3   Northern                                           Unchanged
  4   Southern                                           Unchanged
  999 North West                                         Added
Để cập nhật cơ sở dữ liệu từ một DataAdapter, gọi phương thức Update() như sau đây:
da.Update(ds , "Region");
Đối với một dòng mới trong DataTable, sẽ thực thi stored procedure và xuất ra các mẫu tìn trong DataTable một lần nữa.
New row updated and new RegionID assigned by database
  1   Eastern                                            Unchanged
  2   Western                                            Unchanged
  3   Northern                                           Unchanged
  4   Southern                                           Unchanged
  5   North West                                         Unchanged
Hãy nhìn dòng cuối của DataTable. Tôi đã nhập RegionID trong mã là 999, nhưng sau khi sẽ đổi RegionInsert stored procedure giá trị được đổi thành 5. Có sở dữ liệu thường tạo khoá chính cho bạn.
SqlCommand aCommand = new SqlCommand("RegionInsert" , conn);

aCommand.CommandType = CommandType.StoredProcedure;
aCommand.Parameters.Add(new SqlParameter("@RegionDescription" ,
                            SqlDbType.NChar , 
                            50 , 
                            "RegionDescription"));
aCommand.Parameters.Add(new SqlParameter("@RegionID" , 
                            SqlDbType.Int, 
                            0 , 
                            ParameterDirection.Output ,
                            false , 
                            0 , 
                            0 , 
                            "RegionID" ,   // Defines the SOURCE column
                            DataRowVersion.Default , 
                            null));
aCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
Chuyện gì sẽ xảy ra khi một data adapter phát các lệnh này, các tham số xuất sẽ được ánh xạ trở lại mã nguồn của dòng. Stored procedure có một tham số xuất ánh xạ trở lại DataRow.
Giá trị của UpdateRowSource được cho trong bảng sau:
UpdateRowSource Value
Description
Both
Một stored procedure có thể trả về nhiều tham số xuất và cũng có thể là một cơ sở dữ liệu gồm các mẫu tin đã được cập nhật.
FirstReturnedRecord
Nó trả về một mẫu dữ liệu đơn, nội dung của mẫu tin đó có thể được trộn vào DataRow nguồn. Nó có có ích đối với một bảng có các cột mang giá trị mặc định hoặc tính toán, sau khi một câu lệnh INSERT chúng cần phải được đồng bộ với các DataRow trên máy trạm. Một ví dụ có thể là be 'INSERT (columns) INTO (table) WITH (primarykey)', sau đó là 'SELECT (columns) FROM (table) WHERE (primarykey)'. Các mẫu tin trả về có thể trộn vào tập các dòng.
None
Tất cả dữ liệu trả về từ câu lệnh đều bị vứt bỏ.
OutputParameters
Bất kì tham số xuât nào của câu lệnh đều được ánh xạ vào một cột thích hợp trong DataRow.

Cập nhật một dòng đã có

Cập nhật một dòng có sẵn trong DataTable chỉ là một trường hợp việc sử dụng bộ chỉ mục của lớp DataRow với tên của một cột hoặc số thứ tự của cột, giống như ví dụ sau đây:
r["RegionDescription"]="North West England";
r[1] = "North East England";
Các hai câu lệnh đều cho cùng kết quả:
Changed RegionID 5 description
  1   Eastern                                            Unchanged
  2   Western                                            Unchanged
  3   Northern                                           Unchanged
  4   Southern                                           Unchanged
  5   North West England                                 Modified
Trong quá trính cập nhật cơ sở dữ liệu, trạng của dòng được cập nhật sẽ được gán là Modified.

RowXóa một dòng

Xóa một dòng là kết quả của việc gọi phương thức Delete():
r.Delete();
Một dòng được xóa có trạng thái là Deleted, nhưng bạn không thể đọc các cột từ một dòng đã xoá, nó không còn giá trị nữa. Khi gọi phương thức Update(), tất cả các dòng bị xoá sẽ sử dụng DeleteCommand, trong trường hợp này sẽ chạy stored procedure RegionDelete.

Viết XML xuất

Như bạn đã thấy, DataSet hỗ trợ mạnh việc định nghĩa sơ đồ của nó trong một XML, và bạn có thể đọc dữ liệu từ một tài liệu XML, bạn cũng có thể viết một tài liệu XML.
Phương thức DataSet.WriteXml() cho phép bạn xuất các thành phần khác nhau của dữ liệu được lưu trong DataSet. Bạn có thể chọn chỉ xuất dữ liệu, hoặc dữ liệu và sơ đồ. Mã sau đây đưa ra một ví dụ của cho cả hai loại trên:
ds.WriteXml(".\\WithoutSchema.xml");
ds.WriteXml(".\\WithSchema.xml" , XmlWriteMode.WriteSchema);
File đầu tiên, WithoutSchema.xml được đưa ra dưới đây:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
   <Region>
      <RegionID>1</RegionID>
      <RegionDescription>Eastern                       </RegionDescription>
   </Region>
   <Region>
      <RegionID>2</RegionID>
      <RegionDescription>Western                       </RegionDescription>
   </Region>
   <Region>
      <RegionID>3</RegionID>
      <RegionDescription>Northern                      </RegionDescription>
   </Region>
   <Region>
      <RegionID>4</RegionID>
      <RegionDescription>Southern                      </RegionDescription>
   </Region>
</NewDataSet>
File WithSchema.xml bao gồm cả sơ đồ và dữ liệu của DataSet:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
   <xs:schema id="NewDataSet" xmlns="" 
              xmlns:xs="http://www.w3.org/2001/XMLSchema" 
              xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
      <xs:element name="NewDataSet" msdata:IsDataSet="true">
         <xs:complexType>
            <xs:choice maxOccurs="unbounded">
               <xs:element name="Region">
                  <xs:complexType>
                     <xs:sequence>
                        <xs:element name="RegionID" 
                                    msdata:AutoIncrement="true" 
                                    msdata:AutoIncrementSeed="1" 
                                    type="xs:int" />
                        <xs:element name="RegionDescription" 
                                    type="xs:string" />
                     </xs:sequence>
                  </xs:complexType>
               </xs:element>
            </xs:choice>
         </xs:complexType>
      </xs:element>
   </xs:schema>
   <Region>
      <RegionID>1</RegionID>
      <RegionDescription>Eastern                       </RegionDescription>
   </Region>
   <Region>
      <RegionID>2</RegionID>
      <RegionDescription>Western                       </RegionDescription>
   </Region>
   <Region>
      <RegionID>3</RegionID>
      <RegionDescription>Northern                     </RegionDescription>
   </Region>
   <Region>
      <RegionID>4</RegionID>
      <RegionDescription>Southern                     </RegionDescription>
   </Region>
</NewDataSet>
Chú ý rằng, các thuộc tính mở rộng cho các cột trong một DataSet, như AutoIncrementAutoIncrementSeed - những thuộc tính này tương ứgn với các thuộc tính có thể định nghĩa trong một DataColumn.