1¥ DataSet(数据集)对象

    DataSet是数据集对象,利用数据集,可以在断开数据库连接的情况下操作数据,也可以操作多个数据源的数据。

1$ 认识DataSet对象
1.。数据集把应用程序需要的数据临时保存在本机内存中。
    数据都缓存在本地机器上,不需要一直保持和数据库的连接

2.。应用程序直接从内存中的数据集读取数据,并可以对数据集中的
    数据进行修改,将修改后的数据一起提交给数据库。

3.。数据集不直接和数据库打交道,通过.NET数据提供程序来完成
    和数据库的相互作用,所以独立于任何数据库。

4.。数据集中也包含多个表
    数据集中的数据表集合: DataTableCollection
    数据集中的每个数据表都是一个 DataTable 对象

    数据表中列构成的集合: DataColumnCollection
            每一个数据列: DataColumn

    数据表中行构成的集合: DataRowCollection
            每一个数据行: DataRow
如://打印数据集中的新建表Question中的内容
foreach (DataRow row in dSet.Tables["Question"].Rows)
{
   //输出题目和选项
   Console.WriteLine("{0}\nA.{1}\nB.{2}\nC.{3}\nD{4}",
    row["Question"], row["OptionA"], row["OptionB"],
                   row["OptionC"], row["OptionD"]);

    //输出答案、难度
    Console.WriteLine("正确答案{0}\n难度{1}",
                    row["Answer"],row["Difficulty"]);

   //换行
    Console.WriteLine();

说明:DataRow 表中的每一行数据
      row     循环中定义的代表某一行数据的变量
      Tables  数据集中所有表的集合
      Rows    数据集中某表中的所有行的集合
     

2$ 如何创建DataSet(数据集)

   语法: DataSet 数据集对象 = new DataSet(“数据集的名称字符串”);

   数据集的名称字符串可以有,也可没有,如没有,默认为NewDataSet。
  
   如:DataSet myDataSet = new DataSet();
   或:DataSet myDataSet = new DataSet(“MySchool”);

2¥ DataAdapter(数据适配器)对象
1$ 认识DataAdapter对象
1.。.NET数据提供程序及其DataAdapter类

SQL数据提供程序:SqlDataAdapter
                  使用System.Data.SqlClient命名空间

其他数据库提供程序的DataAdapter类,暂略。。。。。。

2.。数据适配器通过其属性SelectCommand调用一个Command命令,
   可以从数据库中读取数据

3.。数据适配器要把数据放在数据集(DataSet)中,需要使用
    DataAdapter的Fill()方法


4.。数据适配器对象要把修改过的数据保存到数据库,需要使用
    DataAdapter的Update( )方法

2$ 如何填充数据集
1.。创建数据库连接对象(Connetion对象)
2.。创建从数据库查询数据用的SQL语句
3.。利用上面的SQL语句和Connection对象创建DataAdapter对象

语法:
     SqlDataAdapter 对象名 = new SqlDataAdapter
                            (查询用的SQL语句,数据库连接);

4.。调用DataAdapter对象的Fill()方法填充数据集

语法:
     DataAdapter对象.Fill(数据集,“数据表名称字符串”);


特别注意:Fill()方法接收一个数据表名称的字符串参数

    数据集中如没有这个表,则会在数据集中创建一个新表
    数据集中如果有这个表,则会把查出的数据添加到这个数据表中

特别注意:
1)    数据集中的表,按顺序索引引用,如:dataSet.Tables[0]

2)    数据集中的某表的所有行对象的集合,引用,如:
       dataSet.Tables[0].Rows(可用于foreach)

3)    数据集中某表行中的列值,用“数据行对象[“列名”]”取出

    如: row[“TeacherId”]//表中某行列名为TeacheId的数据

3$ 如何保存数据集中的数据
   对数据库中的数据进行更新时,需要相关的命令,.NET提供了一个SqlCommandBuilder对象(构造SQL命令),可以自动生成更新数据库时需要使用的命令。

   步骤:
     1)使用SqlCommandBuilder对象生成更新用的相关命令

      语法:
       SqlCommandBuilder builder =
                  new SqlCommandBuilder(已创建的DataAdapter对象)

     
     2)调用DataAdapter对象的Update()方法

        作用:将Fill()好的DataSet对象中某个表中的内容向数据库中更
              新,更新命令SqlCommandBuilder对象自动生成。

        语法:
        DataAdapter对象.Update(数据集对象,“数据表名称字符串”)

特别注意:SqlCommandBuilder只能操作单个表,即DataAdapter对象中
          使用的SQL语句只能从一个表里查询数据,不能是进行联合
          查询的语句。

特别注意:*** 用Update()方法去更新的表,必须是有主键的表***
              实例见上机任务8 作业3 代码

3¥ DataGridView(数据网格视图)控件

1$ 认识DataGridView控件
1)DataGridView控件,在其中的数据可以直接修改和删除,就像操
   作Excel一样方便。

2)以表格形式显示数据,可以设置为只读,也可以允许编辑数据

3)通过设置DataSource属性指定DataGridView显示那个表的数据
   如:dgvCheck.DataSource = dataSet.Tables["Student"];

4)DataGridView控件的主要属性
  
   Columns         包含的列的集合
   DataSource       DataGridView的数据源
   ReadOnly        是否可以编辑单元格

5)通过Columns属性可以设置DataGridView中每一列的属性
   包括:列宽、列名、是否只读、是否冻结、
         对应数据表中的那一列等

6)DataGridView控件中各列的主要属性
  
   DataPropertyName      绑定的数据列的名称
   HeaderText            列标题文本
   Visible                指定列是否可见
   Frozen             指定水平滚动DataGridView时,列是否移动
   ReadOnly           指定单元格是否为只读

2$ 如何使用DataGridView显示数据  
   1)创建数据库连接对象(Connection)
   2)创建从数据库查询数据用的SQL语句
   3)利用上面的SQL语句和Connection对象创建DataAdapter对象
   SqlDataAdapter 对象名=new SqlDataAdapter(Sql语句,数据库连接);

   4)调用DataAdapter对象的Fill()方法填充数据集
    DataAdapter对象名。Fill(数据集对象,“数据表名称字符串”);

      关于“数据表名称字符串”:
        如数据集中原来就有—查询结果将继续添加到这个表中
        如数据集中原来没有---在数据集中创建这个表,来存放查询结果

   5)以上工作都做完后,还需在代码中指定DataGridView的数据源

      如://指定DataGridView的数据源
          dgvTeacher.DataSource=dataSet.Tables[“Teacher”];

     注意:数据源一旦指定,如没有语句重新指定数据源,则不会发生
           变化,即使数据集发生了重填或更新,也不用重新指定数据
           源。

           但如果数据源根据需要被清空了,再次查询时,就必须重新
           指定数据源了。

3$ 如何利用数据集的更新,从而保存修改后的数据
   1。。如果在DataGridView中修改数据,一般都要求用户确认修改,方
       法是定义一个DialogResul变量,获取用户的选择。

   如:DialogResult dialog = MessageBox.Show("是否确认修改!", "操
                                   作提示", MessageBoxButtons.YesNo,
                                   MessageBoxIcon.Information);

    2。。用户确认后,在进行更新数据集操作。

       1)更新了查询语句,重新填写数据集后更新

           如://清空数据集表中原有的数据
          dataSet.Table[“Stuedent”].Clear();

               //重新指定DataAdapter对象的查询语句
               dataAdapter.SelectCommand.CommandText=sql;//(新语句)

               //用新的查询结果填充数据集
               dataAdapter.Fill(dataSet,”Student”);

        2)不更新查询语句,在控件单元格中直接更改数据后更新
          (示例见BudgetForm.cs)

          如://创建一个SqlCommandBuilder对象,用以自动生成
                更新命令(基于已建好的DataAdapter对象)
        SqlCommandBuilder builder=new SqlCommandBuilder(dataAdapter);

                //用新的命令更新数据集
                dataAdapter.Update(dataSet,”Teacher”);


          关于SqlCommandBuilder:
             SqlCommandBuilder只能操作单个表,不能进行联合查询
             即,使用Update()方法更新后的数据只能写到一个表中。


4$ DataGridView中如何得知查询是否有结果

   类似的:ListView中如没有查询结果时,可判断dr.HasRows是否为真

   而在DataGridView中,可以使用
        “dataSet表名[0]。Rows。count==0”
                                     来判断是否有查询结果。

如:if (dataSet.Tables[0].Rows.Count == 0)   //判断表中是否有查询结果

特别注意:在重新填充数据集前,要把原来表清空,需调用Clear()方法。
          如:dataSet.Tables["Student"].Clear();

          然后重新为DataAdapter对象指定查询的SQL语句,这时需使
          用它的SelectCommand.CommandText属性。
          如:
             //清空表中原有的数据
            dataSet.Tables["Student"].Clear();

           //重新指定DataAdapter对象的查询语句
            dataAdapter.SelectCommand.CommandText = sql;

           //使数据源失效,让DataGridView中的网格彻底消失
           dgvCarsSearch.DataSource = null;

特别注意:
1)如何使文本框变成只读型式(文本框背景变暗,不能输入)
   选中文本框的ReadOnly属性,设置成False

2)如何设置DataGridView中的数据行只能整行选取
   选中DataGridView控件的SelectionModel属性,设置成
   FullRowSelect

3)在程序代码中引用DataGridView控件中的行或列中的数据
   如:
int id =Covert.ToInt32(dgvTicketInfo.SelectedRows[0].Cells[“Id”].Values);

SelectedRows    表示选中的所有行
SelectedRows[0]  表示选中的第一行
Cells            表示当前行中所有的单元格
Cells[“Id”]      表示行中名为Id列的单元格
Values           表示这个单元格中的值

4)如何引用DataRead.Read()方法读取结果中的数据
   如:txtFrom.Text = dataReader["LeaveCity"].ToString();

     作用:使名为txtFrom的文本框中显示Read()方法读到的行中名为“LeaveCity”的那一列的值,并转换成字符串格式。

     很明显,引用方式为:DataReader对象名[“列名”]

5)如果ExecuteScalar()方法没有查询到数据,会返回一个DBNULL类型的数据(表示数据库的空值),可用于条件判断。

6)如何表示Cbo控件中选取了哪一项
   Cbo控件中的选项可以通过LOAD事件载入,也可以在Items属性中手动设置。

   载入或设置后的各个选项,有自己的从0开始的索引。可以再代码中用其索引,引用Cbo控件中的被选定的项。

   如:if (cboSeatType.SelectedIndex < 0)

 意为:如果名为cboSeatType的组合框中的选项的索引小于零。
       根本不可能,亦即组合框中没有选项。

7)如何在代码中获取Rdo控件的文本内容(使用强制转换)
   如:string answer = ((RadioButton)sender).Text;


8)如何使用ShortCutCase属性设置窗口的快捷键
   选中窗体中的某个控件,该控件已经通过代码实现了某种特定的事件响应(如退出按钮的Click事件)

   选中该控件的ShortCutCase属性,单击右侧的下拉按钮
   在该属性列出的组合中选取适当的按钮组合,如:退出Alt+F4.

9)如何将标签或按钮等控件设置成透明
   选中某标签或按钮,选择属性中的BackColor属性
   将其设置成为Web选项卡中的Transparent

10)标签Text属性中的文本如何换行
    设置该标签的AutoSize属性为False
    默认为True,即自动调整标签宽度和大小,显示标签文本,不会自动换行
    改为False后,标签的宽度是固定的,如果文本超过宽度,则自动换行。

11)如何设置DataGridView控件中的列宽
    只能在DataGridView控件的Colums属性中打开编辑列窗口,然后再每列的设置选项中选取Width项手动设置宽度。

12)如何实现多个同种或不同种控件指向同一事件
    多个控件的事件名同名

13)如何向Cbo控件中增加选项
    Cbo控件中有Items属性,不仅可以手动输入Items项,也可以通过代码增加Items项。
    如:  while (c.Read())  //执行Read()方法
             {
               SubjectName = (string)c[0];  //查询结果的第一列
           cmbSubject.Items.Add(SubjectName);  //给cmb控件中增加选项
              }

    这里使用了Items属性的Add()方法,参数为接收Read()查询结果值得字符串变量。

14)如何在代码中引用Cmb控件中的选定项
    cmbDiffLevel.SelectedItem

15)明确ListView和DataGridView的区别
???????????????????????????

16)如果程序中的SqlCommand对象多次使用,那么在再次使用
    之前,必须再次指定新的SQL命令。
    如:cd.CommandText = sql; //重新指定SQL命令

17)菜单项工具类(ToolStripMenuItem)的使用
     详见:上机任务7  第四阶段
    该类表示System.Windows.Forms.MenuStrip 或
            System.Windows.Forms.ContextMenuStrip
          显示的所有项的集合

     如:(ToolStripMenuItem)sender).Tag
   意为:将菜单项工具指向事件触发者(即
         ToolStipMenuItem中的某行),并取其
          Tag值

18)如何产生随机数
    Random random = new Random();   //实例化Random对象
    int n=random.Next(Num)
    Num为取值范围数:0<n<Num

    实例见项目实战 4 p38页

19)Control类和Controls属性
   
   应用如:(项目实战 P41页)

    int index = 0;
     foreach (Control item in this.Controls)    //检查窗体内的所有控件
     {
        if (item is Label)  //如果控件是标签
        {
           index = Convert.ToInt32(item.Tag); //将标签的Tag值赋给index
           if (index!=-1) 
           {
              //更改标签文本为相对应的答案值
              item.Text = QuizHelpper.studentAnswers[index];
            }
         }
      }

     Control类:代表该窗体上的所有控件
    Controls属性:用this引用的窗体属性,
                 this.Controls代表窗体上所有控件的集合。
    item是实例化了的Control对象,代表窗体上的单个控件






     foreach (Control item in this.Controls)    //检查窗体内的所有控件
            {
                if (item is Label)  //如果控件是标签
                {
                    index = Convert.ToInt32(item.Tag);

                    if (index!=-1)
                    {
                        item.Text = QuizHelpper.studentAnswers[index];
                    }
                }
            }

20)控制标签的宽度和颜色,显示进展条
   1.使用“标签名。Width”引用和改变标签的宽度
     // 确定显示分数的label的宽度
       lblResult.Width = lblFullMarkStrip.Width * score / 100;
   2.使用“标签名。BackColor”引用和改变标签的背景颜色
     lblResult.BackColor = Color.Red;
   3.颜色的值应在前面加上Color类名。如:Color.Red

21)如何查询表中的标识列
   如:项目实战 P61页
       sql=”select @@Identity From Users”;
   注意:要使用@@Identity查询标识列,前提是必须先用ExecuteNonQuery查
         询出结果,然后再在结果中查询。

22)LinkLabel控件
    类似于lbl控件,唯一的区别是控件自动显示为链接模式
    至于链接到哪里,还是要用代码实现。

    如:MyQQ/Register窗体中的“申请号码”标签
   代码:RegisterForm registerForm = new RegisterForm();
            registerForm.Show();   //显示了新窗体
            this.Visible = false;  //隐藏了旧窗体

23)如何实现同一窗体上不同按钮或控件单击后,导致画面变化

    在同一个窗体中,为了显示不同的内容,可以通过适时改变多个Panel控件的Visible属性来实现。

    同时,为了使显示效果最佳,也可以通过Panel控件的Location属性,标定两个Panel的显示位置相同。

    如:项目实战P68页
    pnlBaseResult.Location=pnlBaseCondition.Location;

24)注意比较两种不同但很有用的清空语句
    DataGridView控件中的清空
    //清空数据集中的原有数据
     dataSet.Tables["TicketInfo"].Clear();

     ListView控件中的清空
    listView1.Items.Clear();   //清空ListView控件中的原有内容

25)使用dataAdapter倒入cbo选项

try
{
   //创建DataSet对象
   DataSet ds = new DataSet();

   //创建SQL语句
   string sql = "select * from deptInfo";

   //创建DataAdapter对象
   SqlDataAdapter da = new SqlDataAdapter(sql, conn);

   //填充数据集并命名表
   da.Fill(ds, "deptName");

   //利用DataSource属相倒入cbo选项
   cboDeptName.DataSource = ds.Tables["deptName"];   
   //设置cbo的数据源

   cboDeptName.DisplayMember = "DeptName";
   //设置查询结果中的那一列在cbo中显示
   //注意,只有设置了DisplayMember才显示,其他都不显示

   cboDeptName.ValueMember = "id";
   //设置将查询结果中的id值一同存入cbo控件的ValueMember中
 }

26)在C#前台简化时间的输出形式

    Convert.ToDateTime(dr[”bir”]).ToLongDateString());//2001年1月1日

    Convert.ToDateTime(dr[”bir”]).ToShortDateString());//2001-1-1