ADO.NET 4 快速上手(5)——弱類型DataSet(代碼創建)

五、弱類型DataSet(代碼創建)


1.    本地DataSet

A.    在內在中存儲數據,修改立即生效

DataTable customersTable = new DataTable("Customers");
customersTable.Columns.Add("ID", typeof(int));
customersTable.Columns.Add("Name", typeof(string));
            
DataRow oneRow = customersTable.NewRow();

oneRow["ID"] = 0;
oneRow[1] = "Jack";

DataColumn column = customersTable.Columns[0];
oneRow[column] = 1;

customersTable.Rows.Add(oneRow);
customersTable.Rows.Add(new object[] {2, "Fred"});

oneRow.BeginEdit();
oneRow[0] = 3;  // 沒有改變,仍爲1
oneRow.CancelEdit(); // 恢復到BeginEdit時的值

foreach (DataRow row in customersTable.Rows)
{
    Console.WriteLine(row[0] + "    " + row["Name"]);
}

B.    在內在中存儲數據,修改批量生效

DataTable customersTable = new DataTable("Customers");
// do something to customersTable
customersTable.AcceptChanges(); // 提交所有行的更改
customersTable.RejectChanges(); // 拒絕最後一次提交後的更改

立即生效,馬上驗證數據有效性:

DataTable customersTable = new DataTable("Customers");
            
DataColumn column = customersTable.Columns.Add("Name", typeof(string));
column.MaxLength = 3;

DataRow oneRow = customersTable.NewRow();
customersTable.Rows.Add(oneRow);
oneRow["Name"] = "Jack123456"; // 這行拋異常,字符串超長

下面代碼說明,行的BeginEdit()到EndEdit()之間,對行數據的修改,若導致數據不完整或違反其他規則,不拋出異常,也不直接修改表中數據。此間可以通過CancelEdit()回滾修改。行的EndEdit()被調用,才批量驗證數據有效性。但修改仍未生效。

直到調用行或表級別上的AcceptChanges()時,數據才被批量提交。在表、行級別上調用AcceptChanges(),自動執行EndEdit();調用RejectChanges()時,自動調用CancelEdit()。

DataTable customersTable = new DataTable("Customers");
            
DataColumn column = customersTable.Columns.Add("Name", typeof(string));
column.MaxLength = 3;

DataRow oneRow = customersTable.NewRow();
customersTable.Rows.Add(oneRow);
oneRow.BeginEdit();
oneRow["Name"] = "Jack123456"; // 這行不拋異常
oneRow.EndEdit(); // 這行拋異常,字符串超長
customersTable.AcceptChanges();

C.    DataSet

DataTable customersTable = new DataTable("Customers");
DataSet dataSet = new DataSet();
dataSet.Tables.Add(customersTable);

D.    聚合計算

DataTable customersTable = new DataTable("Customers");
customersTable.Columns.Add("Nmae", typeof(string));
customersTable.Columns.Add("Salary", typeof(float));

customersTable.Rows.Add(new object[] { "Jack", 8000 });
customersTable.Rows.Add(new object[] { "Tommy", 3500 });

float result = (float)customersTable.Compute("Sum(Salary)", "");
Console.WriteLine(result);

2.    數據業務規則驗證

DataTable customersTable = new DataTable("Customers");
// 驗證事件
customersTable.ColumnChanging += (sender, e) => {
    if (e.Column.ColumnName == "Age")
    {
        // ProposedValue:已被更改後的值,但未生效
        if ((int)e.ProposedValue < 0 || (int)e.ProposedValue > 100)
        {
            e.Row.SetColumnError(e.Column, "年齡超限");
        }
    }
};

DataColumn column = customersTable.Columns.Add("Age", typeof(int));
            
DataRow oneRow = customersTable.NewRow();
customersTable.Rows.Add(oneRow);

oneRow.ClearErrors();
oneRow.BeginEdit();
oneRow["Age"] = 105;
// 行級別監視
if (oneRow.HasErrors)
{
    // show error
    oneRow.CancelEdit();
}
else
{
    oneRow.EndEdit();
}

// 表級別監視
if (customersTable.HasErrors)
{
    DataRow[] errorRows = customersTable.GetErrors();
    // show error
    string errorRowText = errorRows[0].GetColumnError(0);
    Console.WriteLine(errorRowText);

    customersTable.RejectChanges();
}
else
{
    customersTable.AcceptChanges();
}

3.    數據提取

A.    主鍵搜索

DataTable customersTable = new DataTable("Customers");
            
DataColumn column = customersTable.Columns.Add("ID", typeof(int));
customersTable.Columns.Add("name", typeof(string));

// 只能在主鍵上搜索
customersTable.PrimaryKey = new DataColumn[] { column };

customersTable.Rows.Add(new object[] {1, "Jack"});
            
DataRow row = customersTable.Rows.Find(1);
Console.WriteLine(row[1]);

B.    搜索條件

DataTable customersTable = new DataTable("Customers");
            
customersTable.Columns.Add("ID", typeof(int));
DataColumn column = customersTable.Columns.Add("name", typeof(string));

customersTable.Rows.Add(new object[] {100, "Jack"});

DataRow[] rows = customersTable.Select("name = 'Jack'");
if (rows.Length > 0)
{
    Console.WriteLine(rows[0][0]);
}

4.    DataView

DataTable包含實際的DataRow實例,DataView不包含DataRow實例,而包含了引用實際DataRow索引,指向各行。

DataTable employeesTable = new DataTable("Customers");
employeesTable.Columns.Add("Nmae", typeof(string));
employeesTable.Columns.Add("Salary", typeof(float));

employeesTable.Rows.Add(new object[] { "Jack", 8000 });
employeesTable.Rows.Add(new object[] { "Tommy", 3500 });

DataView view = new DataView(employeesTable);
view.RowFilter = "Salary > 0";
view.Sort = "Salary";

Console.WriteLine(view[0][0]);
Console.WriteLine(view[1][0]);

5.    讀取外部數據

從外存(數據庫)載入數據到內存(DataSet、DataTable)。

DataTable userTable = new DataTable();
DataSet dataSet = new DataSet();
using (SqlConnection conn = new SqlConnection(
    "Data Source=localhost;Initial Catalog=SettingKnowledgeManagement;Integrated Security=True"))
{
    SqlDataAdapter adapter = new SqlDataAdapter("select * from tb_user", conn);
                
    // 或:
    //SqlDataAdapter adapter2 = new SqlDataAdapter();
    //adapter2.SelectCommand = new SqlCommand("select * from user", conn);

    // Fill方法會自動打開數據庫連接,完成後自動關閉
    adapter.Fill(userTable);
    adapter.Fill(dataSet, "userTable");
}

6.    數據更新

A.    將數據存回數據庫

DataTable userTable = new DataTable();
using (SqlConnection conn = new SqlConnection(
    "Data Source=localhost;Initial Catalog=SettingKnowledgeManagement;Integrated Security=True"))
{
    SqlDataAdapter adapter = new SqlDataAdapter();
    SqlCommand cmd = new SqlCommand("select * from tb_user", conn);
    adapter.SelectCommand = cmd;

    adapter.Fill(userTable);

    cmd = new SqlCommand("insert into tb_user values(@username, @password)", conn);
                
    // 返回自動編號需加此:
    // cmd = new SqlCommand("insert into tb_user values(@username, @password); set @ID = @@IDENTITY;", conn);

    cmd.Parameters.Add("@username", SqlDbType.VarChar, 255, "your name");
    cmd.Parameters.Add("@password", SqlDbType.VarChar, 255, "your password");

    // 返回自動編號需加此:
    //SqlParameter returnParam = cmd.Parameters.Add("@ID", SqlDbType.BigInt, 0, "id");
    //returnParam.Direction = ParameterDirection.Output;

    adapter.InsertCommand = cmd;

    cmd = new SqlCommand("update tb_user set password = @password where username = @username", conn);
    cmd.Parameters.Add("@username", SqlDbType.VarChar, 255, "username");
    cmd.Parameters.Add("@password", SqlDbType.VarChar, 255, "password");
    adapter.UpdateCommand = cmd;

    cmd = new SqlCommand("delete from tb_user where username = @username", conn);
    cmd.Parameters.Add("@username", SqlDbType.VarChar, 255, "username");
    adapter.DeleteCommand = cmd;

    DataRow[] rows = userTable.Select("username = 'your name'");
    if (rows.Length > 0)
    {
        rows[0][1] = "your new password";
    }

    // 更新表到數據庫
adapter.Update(userTable);
userTable.AcceptChanges();
}

B.    自動生成更新命令

注意:只能生成單表查詢,不能有關聯表;表必須有主鍵或有唯一約束;列名不能包含空格。

DataTable userTable = new DataTable();
using (SqlConnection conn = new SqlConnection(
    "Data Source=localhost;Initial Catalog=SettingKnowledgeManagement;Integrated Security=True"))
{
    SqlDataAdapter adapter = new SqlDataAdapter();
    // 指定select
    adapter.SelectCommand = new SqlCommand("select * from tb_user", conn);

    // 自動生成insert, update, delete命令,與select對應
    SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

    adapter.Fill(userTable);
    userTable.Rows.Add(new object[] {"Jack", "my password"});
    adapter.Update(userTable);
    userTable.AcceptChanges();
}
發佈了32 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章