C#数据库入门-013:数据集和数据适配器

一:DataSet和DataAdapter
    DataSet完全独立于数据源,可以和数据源连接或完全断开。基本作用是为存储在内存缓存中的数据提供关系视图。
    DataAdapter可以作为数据集和数据源之间的桥梁。没有它,数据集就不能访问任何类型的数据源。
    1: 如果只想读取和显示数据,则只需要使用数据读取器即可。
        如果需要处理数据并更新数据库,这是就需要用到数据集。
        数据适配器可以使用数据读取器填充数据集。
    2: 数据集
        允许在本地高速缓存中存储和修改大量数据,把数据看做表,以脱机方式处理数据。
        数据集就像一只水桶,可以装水,但需要外部管道把水引入。即需要数据适配器来填充数据,支持对数据源的访问。
        数据集-->数据适配器-->数据源

二:DataSet和DataAdapter的使用
    1: 数据集的构造
        DataSet ds = new DataSet();//默认名为NewDataSet
        DataSet ds = new DataSet("myds");

        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt = @"select productname , unitprice from products where unitprice < 20";

        conn.Open();
        SqlDataAdapter da = new SqlDataAdapter(sqlComTxt, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "products");

        DataTable dt = ds.Tables["products"];

        foreach (DataRow row in dt.Rows)
        {
            foreach (DataColumn col in dt.Columns)
            {
                Console.WriteLine(row[col]);
            }
        }
    2: 数据集的筛选和排序
        没有显式打开连接,调Fill时,如果连接未打开,该方法会自动打开,填充完后,自动关闭连接。
        如果是手动打开的,则该方法不会再打开连接了,而且也不会在之后自动关闭。
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt1 = @"select * from customers ";//后面接个空格很重要
        String sqlComTxt2 = @"select * from products where unitprice < 10";
        String sqlComTxt = sqlComTxt1 + sqlComTxt2;

        SqlDataAdapter da = new SqlDataAdapter(sqlComTxt, conn);
        da.SelectCommand = new SqlCommand(sqlComTxt, conn);

        DataSet ds = new DataSet();
        //每个查询返回一个结果集,每个结果集都存储在单独的DataTable对象中。
        da.Fill(ds, "dstable");

        DataTableCollection dtc = ds.Tables;

        string filter1 = "country = 'Germany'";
        string sort = "companyname asc";
        //select * from customers where country = 'Germany' ORDER BY companyname ASC

        foreach (DataRow row in dtc["dstable"].Select(filter1, sort))//dtc[0].Select(filter1, sort)
        {
            Console.WriteLine("{0}/t{1}", row["companyname"].ToString(), row["contactname"].ToString());
        }

        foreach (DataRow row in dtc["dstable1"].Rows)//dtc[1].Rows
        {
            Console.WriteLine("{0}/t{1}", row["productname"].ToString(), row["unitprice"].ToString());
        }
    3: 数据视图
        数据视图也可以完成动态筛选和排序数据所包含的数据。
        可以创建存储在底层数据表中的数据的动态视图,以反映对其内容和数据数据所作的变化。
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt = "select contactname, country from customers";

        SqlDataAdapter da = new SqlDataAdapter(sqlComTxt, conn);
        da.SelectCommand = new SqlCommand(sqlComTxt, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        //表,筛选器SELECT,排序列ORDER BY。
        DataView dv = new DataView(dt, "country='Germany'", "contactname", DataViewRowState.CurrentRows);

        foreach (DataRowView drv in dv)
        {
            for (int index = 0; index < dv.Table.Columns.Count; index++)
            {
                Console.Write(drv[index] + "/t");
            }
            Console.WriteLine();
        }
    4: 修改数据集中的数据
        对数据集所做的变化不会自动保存到数据库中。如果要保存的话,需要再次连接到数据库并显式的完成更新。参考第三部分。
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt = "select * from employees where country = 'UK'";

        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = new SqlCommand(sqlComTxt, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        dt.Columns["firstname"].AllowDBNull = true;

        dt.Rows[0]["city"] = "wilmingtom";

        DataRow dr = dt.NewRow();
        dr["firstname"] = "Roy";
        dr["lastname"] = "Beatty";
        dr["titleofcourtesy"] = "Sir";
        dr["city"] = "Birmingham";
        dr["country"] = "UK";
        dt.Rows.Add(dr);

        foreach (DataRow row in dt.Rows)
        {
            Console.WriteLine("{0}/t{1}/t{2}",
                row["firstname"].ToString(), row["lastname"].ToString(), row["city"].ToString());
        }

三:将变化保存到数据源中
    数据适配器如何用数据集中的数据更新和同步数据源。UpdateCommand, InsertCommand, DeleteCommand。
    1: UpdateCommand
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt1 = "select * from employees where country = 'UK' ";
        String sqlComTxt2 = "update employees set city = @city where employeeid = @employeeid";

        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = new SqlCommand(sqlComTxt1, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        dt.Rows[0]["city"] = "wilmingtom";

        foreach (DataRow row in dt.Rows)
        {
            Console.WriteLine("{0}/t{1}/t{2}",
                row["firstname"].ToString(), row["lastname"].ToString(), row["city"].ToString());
        }

        SqlCommand cmd = new SqlCommand(sqlComTxt2, conn);
        cmd.Parameters.Add("@city", SqlDbType.NVarChar, 15, "city");
        //默认情况是从数据表的当前版本中提取,所以city直接取就可以
        //但是employeeid必须从修改之前的版本中提取值,这样,如果主键发生变化,就可以在数据库表中反问正确的行。
        SqlParameter parm = cmd.Parameters.Add("@employeeid", SqlDbType.Int, 4, "employeeid");
        parm.SourceVersion = DataRowVersion.Original;

        //将变化保存到数据库中
        //数据适配器会在dstable数据表中查找所有已修改的行,并把对它们的所有更新都提交给数据库
        da.UpdateCommand = cmd;
        da.Update(ds, "dstable");
    2: InsertCommand
        调用Update命令时,将搜索以前添加到表中的所有新行,并将其保存到数据库中。
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt1 = @"select * from employees where country = 'UK' ";
        String sqlComTxt2 = @"insert into employees (firstname, lastname, titleofcourtesy, city, country)
            values(@firstname, @lastname, @titleofcourtesy, @city, @country)";

        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = new SqlCommand(sqlComTxt1, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        DataRow dr = dt.NewRow();
        dr["firstname"] = "Roy";
        dr["lastname"] = "Beatty";
        dr["titleofcourtesy"] = "Sir";
        dr["city"] = "Birmingham";
        dr["country"] = "UK";
        dt.Rows.Add(dr);

        foreach (DataRow row in dt.Rows)
        {
            Console.WriteLine("{0}/t{1}/t{2}",
                row["firstname"].ToString(), row["lastname"].ToString(), row["city"].ToString());
        }

        SqlCommand cmd = new SqlCommand(sqlComTxt2, conn);
        cmd.Parameters.Add("@firstname", SqlDbType.NVarChar, 10, "firstname");
        cmd.Parameters.Add("@lastname", SqlDbType.NVarChar, 20, "lastname");
        cmd.Parameters.Add("@titleofcourtesy", SqlDbType.NVarChar, 25, "titleofcourtesy");
        cmd.Parameters.Add("@city", SqlDbType.NVarChar, 15, "city");
        cmd.Parameters.Add("@country", SqlDbType.NVarChar, 15, "country");

        //InsertCommand,会在dstable表中查找所有的新行,并把对它们的所有插入操作都提交给数据库
        da.InsertCommand = cmd;
        da.Update(ds, "dstable");
    3: DeleteCommand属性
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt1 = @"select * from employees where country = 'UK' ";
        String sqlComTxt2 = @"delete from employees where employeeid = @employeeid";

        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = new SqlCommand(sqlComTxt1, conn);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        SqlCommand cmd = new SqlCommand(sqlComTxt2, conn);
        cmd.Parameters.Add("@employeeid", SqlDbType.Int, 4, "employeeid");

        //选择要删除的行,并删除它。由于不关心ID,所以直接删除名,同样的DeleteCommand命令中会反映出来
        String filter = @"firstname = 'Roy' and lastname = 'Beatty'";
        foreach (DataRow row in dt.Select(filter))
        {
            row.Delete();
        }

        //InsertCommand,会在dstable中查找所有的新行,并把它们的所有插入操作都提交给数据库
        da.DeleteCommand = cmd;
        da.Update(ds, "dstable");

        foreach (DataRow row in dt.Rows)
        {
            Console.WriteLine("{0}/t{1}/t{2}",
                row["firstname"].ToString(), row["lastname"].ToString(), row["city"].ToString());
        }
    4: 命令构建器
       
        conn = new SqlConnection(@"
            server=./sqlexpress; integrated security=true; database=northwind");

        String sqlComTxt1 = @"select * from employees where country = 'UK'";

        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = new SqlCommand(sqlComTxt1, conn);

        SqlCommandBuilder scb = new SqlCommandBuilder(da);

        DataSet ds = new DataSet();
        da.Fill(ds, "dstable");

        DataTable dt = ds.Tables["dstable"];

        DataRow dr = dt.NewRow();
        dr["firstname"] = "Roy";
        dr["lastname"] = "Beatty";
        dr["titleofcourtesy"] = "Sir";
        dr["city"] = "Birmingham";
        dr["country"] = "UK";
        dt.Rows.Add(dr);

        foreach (DataRow row in dt.Rows)
        {
            Console.WriteLine("{0}/t{1}/t{2}",
                row["firstname"].ToString(), row["lastname"].ToString(), row["city"].ToString());
        }

        da.Update(ds, "dstable");

        //注解:
        SqlCommandBuilder scb = new SqlCommandBuilder(da);
        //等价于:
        String sqlComTxt2 = @"insert into employees (firstname, lastname, titleofcourtesy, city, country)
            values(@firstname, @lastname, @titleofcourtesy, @city, @country)";
        SqlCommand cmd = new SqlCommand(sqlComTxt2, conn);
        cmd.Parameters.Add("@firstname", SqlDbType.NVarChar, 10, "firstname");
        cmd.Parameters.Add("@lastname", SqlDbType.NVarChar, 20, "lastname");
        cmd.Parameters.Add("@titleofcourtesy", SqlDbType.NVarChar, 25, "titleofcourtesy");
        cmd.Parameters.Add("@city", SqlDbType.NVarChar, 15, "city");
        cmd.Parameters.Add("@country", SqlDbType.NVarChar, 15, "country");
        //使用
        SqlConnection conn = new SqlConnection(strConnection));//连接数据库   
        SqlDataAdapter myAdapter = new SqlDataAdapter();//new一个adapter对象   
        SqlCommand myCommand = new SqlCommand("select * from "+strTblName),(SqlConnection) conn); //cmd   
        SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter); //new 一个 SqlCommandBuilder   
        myAdapter.InsertCommand = myCommandBuilder .GetInsertCommand();//插入   
        myAdapter.UpdateCommand = myCommandBuilder .GetUpdateCommand();//更新   
        myAdapter.DeleteCommand = myCommandBuilder .GetDeleteCommand();//删除   
        conn.Open();//打开数据库   
        myAdapter.Update(ds); //更新ds到数据库   
        conn.Close();//关闭数据库

四:使用数据集和XML
    XML是数据交换的基本格式,将数据从数据集写入XML文件中
    conn = new SqlConnection(@"
        server=./sqlexpress; integrated security=true; database=northwind");

    String sqlComTxt1 = @"select productname, unitprice from products";

    SqlDataAdapter da = new SqlDataAdapter();
    da.SelectCommand = new SqlCommand(sqlComTxt1, conn);

    conn.Open();

    DataSet ds = new DataSet();
    da.Fill(ds, "dstable");

    ds.WriteXml("xml.xml");
    //写入文件
    <?xml version="1.0" standalone="yes" ?>
    <NewDataSet>
        <dstable>
            <productname>Chai</productname>
            <unitprice>18.0000</unitprice>
        </dstable>
        <dstable>
            <productname>Chang</productname>
            <unitprice>19.0000</unitprice>
        </dstable>
    </NewDataSet>

五:在没有数据集的情况下使用数据表
    在只有一个表的情况下。
    conn = new SqlConnection(@"
        server=./sqlexpress; integrated security=true; database=northwind");

    String sqlComTxt1 = @"select productname, unitprice from products where unitprice < 20";

    conn.Open();

    SqlDataAdapter da = new SqlDataAdapter(sqlComTxt1, conn);

    DataTable dt = new DataTable();
    da.Fill(dt);

    foreach (DataRow row in dt.Rows)
    {
        foreach (DataColumn col in dt.Columns)
            Console.WriteLine(row[col]);
        Console.WriteLine();
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值