如鹏网.Net基础2 第七章:ADO.Net

1、ExecuteNonQuery;ExecuteScalar;ExecuteQuery;

2、什么是SQL注入漏洞?怎么避免。

3、DataSet、DataTable、DataRow的关系是什么?DataSet和DataReader的区别是什么?

4、编写一个MySqlHelper;

5、什么是事务?

6、使用MySqlHelper实现增删改查。

7、ADO.Net连接SQLServer

------------------------------------------------

第 1 节 ADO.Net简介

ADO.Net是.Net中提供的标准访问数据库的接口,访问不同的DBMS的底层方法是不一样的,ADO.Net把访问数据库方法进行了统一,访问MYSQL,Oracle,SQLServer等不同的数据库的用法几乎一模一样。

ADO.Net是规范,被不同的数据库厂商提供ADO.Net的实现,称之为ADO.Net驱动,每个厂商提供的驱动可以用来操作自己的数据库。

 

MYSQL的.Net驱动mysql-connector-net-***.msi下载地址:

1)http://www.cncrk.com/downinfo/41149.html

2)http://www.cr173.com/soft/50789.html

3)http://dev.mysql.com/downloads/file.php?id=405442

4)http://download.csdn.net/detail/du_niao/6500785

 

新建项目,添加引用→“扩展”,添加Mysql.Data;如果是直接解压版,然后直接添加对MySql.Data.dll文件的引用;

using (MySqlConnection conn =
    new MySqlConnection("Server=localhost;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand()) { conn.Open();//一定要在执行前Open数据库连接 cmd.CommandText = "Insert into T_Users(UserName,Password) values('中国人','123')"; int rowCount = cmd.ExecuteNonQuery(); Console.WriteLine("受影响的行数"+rowCount); }

解释一下代码:

MySqlConnection、MySqlCommand实现了IDisposable接口,因此使用using进行资源释放;

"Server=localhost;Database=study1;uid=root;pwd=root;Charset=utf8"叫连接字符串,Server是Mysql服务器的地址,Database是连接的数据库,uid、pwd是用户名和密码,采用utf8编码。

conn.Open():在执行MySqlCommand之前一定要先打开数据库连接,否则会报错。

ExecuteNonQuery是执行Update、Insert、Delete等非查询语句,返回值为受影响的行数。

 

 

------------------------------------------------
第 2 节 执行Insert语句

ExecuteNonQuery是执行Update、Insert、Delete等非查询语句,返回值为受影响的行数。

------------------------------------------------
第 3 节 ExecuteScalar()

ExecuteScalar:执行查询,并返回查询所返回的结果集中第一行的第一列,忽略其他行列。一般用来简单的获得只有一行一列的查询结果的值。聚合函数

案例1:

cmd.CommandText = "Select count(*) from T_Users";

long count = (long)cmd.ExecuteScalar();

案例2:

cmd.CommandText = "Select Password from T_Users where UserName='admin'";

string pwd = (string)cmd.ExecuteScalar();

if (string.IsNullOrEmpty(pwd))

{   

   Console.WriteLine("找不到admin");

}

else

{    

   Console.WriteLine("admin的密码:" + pwd);

}

------------------------------------------------
第 4 节 ExecuteReader

cmd.CommandText = "select * from T_Users";
using (MySqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { long id = reader.GetInt64("Id"); string userName = reader.GetString("UserName"); string password = reader.GetString("Password"); Console.WriteLine("id=" + id + ";UserName=" + userName + ";Password=" + password); } }

注意:Reader的遍历、读取时需要Connection保持连接,如果关闭了Connection,使用Reader会出错。

也可以根据列序号获取列的值,效率略高,不过程序不容易读;通过reader.GetOrdinal("Age")获得列名对应的列序号。

------------------------------------------------
第 5 节 SQL注入漏洞说明

  a' or 'a' ='a

------------------------------------------------
第 6 节 参数化查询1

为什么这样就不会有“SQL注入漏洞”?

参数化查询优点:安全;效率高(SQL预编译)

陷阱:

不要用MySqlParParameter(string ParameterName,object value)的这个函数,因为("Age",0)会被匹配成MySqlParameter(string ParameterName,MySqlDbType dbType)这个构造函数。

 

------------------------------------------------
第 7 节 参数化查询2

/*
using(MySqlConnection conn = new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "Insert into @p(UserName,Password) values(@un,@pwd)";
    cmd.Parameters.Add(new MySqlParameter { ParameterName = "@p", Value = "t_users" });
    cmd.Parameters.Add(new MySqlParameter { ParameterName="@un",Value="rupeng"});
    cmd.Parameters.Add(new MySqlParameter { ParameterName="@pwd",Value="123456"});
    cmd.ExecuteNonQuery();
}*/
 
/*
using(MySqlConnection conn = new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "Insert into T_Users(UserName,Password,Age) values(@un,@pwd,@Age)";
    cmd.Parameters.Add(new MySqlParameter("@un","test1"));
    cmd.Parameters.Add(new MySqlParameter("@pwd", "321"));
 
    //int i = 0;
    //cmd.Parameters.Add(new MySqlParameter("@Age", i));
    // cmd.Parameters.Add(new MySqlParameter("@Age", 0));
    cmd.Parameters.Add(new MySqlParameter("@Age",(object)0));
    cmd.ExecuteNonQuery();
}*/

  关键字,表名,字段名等是不能用参数化进行替。

  编译器重载匹配

    int i=0; 调用i  //

    (object)0   //常量

------------------------------------------------

第 8 节 读取数据库中的null值

 

使用IsDBNull获取指定序号的列的值是否为null

int? age=null;

if (!reader.IsDBNull(reader.GetOrdinal("Age")))

{

    age = reader.GetInt32("Age");

}

 

using (MySqlConnection conn =
new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = "select * from T_Users;"; using (MySqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { string username = reader.GetString("UserName"); // string password = reader.GetString("Password"); string password; if (reader.IsDBNull(reader.GetOrdinal("Password"))) { password = null; } else { //GetString/GetInt32 无法读取数据库中的null值 //需要提前用IsDBNull判断 password = reader.GetString("Password"); } int? age; if (reader.IsDBNull(reader.GetOrdinal("Age"))) { age = null; } else { age = reader.GetInt32("Age"); } // int age = reader.GetInt32("Age"); Console.WriteLine("用户名:"+username+";密码:"+ (password==null?"不知道密码":password)+";年龄:"+ (age==null?"不知道年龄":age.ToString())); } } }

  reader.GetString/GetInt32无法读取字段值为null的数据,需要使用reader.IsDBNull(reader.GetOrdinal("Password"))先进行判断。

------------------------------------------------
第 9 节 离线结果集入门

DataReader是服务器结果集游标的体现,所有查询出来的数据都在MySQL服务器上。好处是:当查询结果数据量大的时候避免占用本地内存。不过大部分项目中都会避免大查询结果,

因此缺点就明显了:

  读取的时候必须保持Connection,

  不仅用起来麻烦,而且会较长时间占用MySQL服务器的连接资源。

DataSet是一个离线结果集容器,它把结果数据放到本地内存中。因为查询结果可能会包含多个表,因此DataSet包含若干DataTable(ds.Tables)、DataTable包含若干DataRow(dt. Rows)。

用法1:

DataSet ds = new DataSet();
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd); adapter.Fill(ds); DataTable table = ds.Tables[0];

DataSet 可以盛放多个查询结果集到DataTable ;DataAdapter还可以对结果进行傻瓜化更新、删除、修改。我们一般查询结果集就一个DataTable, DataAdapter的傻瓜化更新不适合于正式的项目,因此有更简单的用法

DataTable dt = new DataTable();

dt.Load(reader);

把DataTable声明到using外,using外再使用查询结果。

遍历DataTable:

for (int i = 0; i < dt.Rows.Count; i++)
{
    DataRow row = dt.Rows[i]; string name = row.IsNull("Name")?null:(string)row["Name"];//NULL处理 Console.WriteLine("name"+name); }

案例代码:

/*
    using (MySqlConnection conn =
    new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
    using (MySqlCommand cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "select * from t_users";
        using (MySqlDataReader reader = cmd.ExecuteReader())
        {
            DataTable dt = new DataTable();
            dt.Load(reader);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow row = dt.Rows[i];
                int id = (int)row["Id"];//下标方式获得是object
                string username = (string)row["UserName"];
 
                //做很复杂的io操作,把username存到文件中
                //这样就会长期占据Connection
 
            // object obj = row["Password"];
                //if(row["Password"]==DBNull.Value)//返回的不是null,而是DBNull
                          
                //string password = (string)row["Password"];
                //int age = (int)row["Age"];
                string password = row.IsNull("Password") ? null : (string)row["Password"];
                int? age = row.IsNull("Age") ? (int?)null : (int)row["Age"];
 
                Console.WriteLine("id=" + id + ";Username=" + username
                    +";username="+username+";age="+age);
            }
        }
    }*/
 
/*
DataTable table  = new DataTable();
using (MySqlConnection conn =
    new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "select * from t_users";
    using (MySqlDataReader reader = cmd.ExecuteReader())
    {
        table.Load(reader);//加载到table中
    }
}
 
for (int i = 0; i < table.Rows.Count; i++)
{
    DataRow row = table.Rows[i];
    int id = (int)row["id"];
    string username = (string)row["UserName"];
    Console.WriteLine(id+":"+username);
}
*/

 

------------------------------------------------
第 10 节 离线结果集要注意的问题

  row.IsNull("Password")  或  row["Password"] == DBNull.Value

  数据库连接不能长期占用。读完数据就关闭。别的代码在外面。

------------------------------------------------
第 11 节 MySqlHelper需求分析

  1.AD.Net的连接字符串写到配置文件中。

  2.每次操作数据库都要写一大堆代码,太麻烦,需要封装一个简化的ADO.Net操作的库出来:

    配置文件中设置连接字符串;

    简化连接的创建;

    简化SQL的执行。

  3.如果一个操作要执行多条SQL语句,如果每条都打开一次连接->执行->关闭连接的话,效率非常低,而且会有“事务”的问题。因此应该提供“打开、执行、关闭”这样的方法,也要提供“使用现有连接执行”的方法。

  4.参数代查询的查询参数个数是不确定的,用可变长度参数会更方便。

  5.为了方便大部分情况下的小结果集,执行查询返回DataTable。

  MySqlHelper方法规划:

    public static MySqlConnection CreateConnection();//得到已经打开的连接

    //1.读取配置文件

    //2.创建连接

    //3.打开连接

    public static int ExectueNonQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters);

    public static int ExectueNonQuery( string sql, params MySqlParameter[] parameters);

    //1.

    public static object ExecuteScalar(MySqlConnection conn, string sql, params MySqlParameter[] parameters);

    public static object ExecuteScalar(string sql, params MySqlParameter[] parameters);

    public static DataTable ExecuteQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters);

    public static DataTable ExecuteQuery( string sql, params MySqlParameter[] parameters);

------------------------------------------------
第 12 节 实现MysqlHelper

 

连接字符串一般配置到App.config(网站是Web.config)中的<connectionStrings>段中

使用ConfigurationManager类(添加对System.Configuration的引用)读取

string connstr =

           ConfigurationManager.ConnectionStrings["connstr"].ConnectionString

注意:

1、注意不要修改App.config的名字为App1.config之类的,必须叫App.config(网站是Web.config)

2、一定要保证代码中的名字和配置文件中的名字一致(初学者容易犯错的,一般提示“初始化代码错误”这个错误就是因为两者名字不一致造成的)

using MySql.Data.MySqlClient;
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ADONETTest2 { class MySqlHelper { private static readonly string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; public static MySqlConnection CreateConnection() { //using (MySqlConnection conn = new MySqlConnection(connstr)) MySqlConnection conn = new MySqlConnection(connstr); conn.Open(); return conn; } public static int ExecuteNonQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters) { using (MySqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; /* foreach (MySqlParameter p in parameters) { cmd.Parameters.Add(p); }*/ cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters) { using (MySqlConnection conn = CreateConnection()) { return ExecuteNonQuery(conn, sql, parameters); } } public static object ExecuteScalar(MySqlConnection conn, string sql, params MySqlParameter[] parameters) { using (MySqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); return cmd.ExecuteScalar(); } } public static object ExecuteScalar(string sql, params MySqlParameter[] parameters) { using (MySqlConnection conn = CreateConnection()) { return ExecuteScalar(conn, sql, parameters); } } public static DataTable ExecuteQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters) { DataTable table = new DataTable(); using (MySqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); using (MySqlDataReader reader = cmd.ExecuteReader()) { table.Load(reader); } } return table; } public static DataTable ExecuteQuery(string sql, params MySqlParameter[] parameters) { using (MySqlConnection conn = CreateConnection()) { return ExecuteQuery(conn, sql, parameters); } } } }

 

  

------------------------------------------------
第 13 节 获得自动增长字段的值

1、使用LAST_INSERT_ID()获取“最后一次插入的自动递增列的值”

2、需要注意Insert语句和select LAST_INSERT_ID()一定要在要在同一个连接中。

using (MySqlConnection conn = MySqlHelper.CreateConnection())
{
    MySqlHelper.ExecuteNonQuery(conn,
        "insert into t_users(UserName,Password) values('我几时我','123')"); object o = MySqlHelper.ExecuteScalar(conn, "select Last_Insert_Id()"); //Last_Insert_Id()是获取当前连接中,最近一次自动递增字段的值 ulong id = (ulong)o;//无符号的long  Console.WriteLine(id); }

可以Insert、LAST_INSERT_ID()在同一个连接中单独执行,也可以把LAST_INSERT_ID()放到insert语句后面用;分割(使用ExecuteScalar执行即可)

ulong id = (ulong)MySqlHelper.ExecuteScalar("insert into t_users(UserName,Password) values('我几时我','123');select last_insert_id()");
Console.WriteLine(id);

 

------------------------------------------------
第 14 节 事务的原子性

  事务(Transaction)有四大特征:原子性,一致性,隔离性,持久性。

  原子性:“几个操作要么都成功,要么都失败”!

事务的几个关键环节:

1)要在一个连接中;

2)启动事务:MySqlTransaction tx = conn.BeginTransaction(); 

3)操作结束后执行tx.Commit() 提交事务;

4)如果执行出错,则tx.Rollback()回滚(当前事务的操作全部取消)。

 MySqlTransaction tx = conn.BeginTransaction();
    try { MySqlHelper.ExecuteNonQuery(conn, "Update t_accounts Set Amount=Amount-1000 where Number='0001'"); string s = null; s.ToLower(); MySqlHelper.ExecuteNonQuery(conn, "Update t_accounts Set Amount=Amount+1000 where Number='0002'"); tx.Commit(); } catch (Exception ex) { tx.Rollback(); }

 注意:必须是同一个连接,创建后,还得使用创建的连接执行SQL语句!每个MySqlHelper.Excute的方法必须使用创建的连接conn。

            using (MySqlConnection conn = MySqlHelper.CreateConnection())
            using(MySqlTransaction tx=conn.BeginTransaction( )) { try { //必须是同一个连接conn不能忘 ulong id = (ulong)MySqlHelper.ExcuteScalar(conn,"Insert into T_Users (UserName,Password)values(@UserName,@Password);select LAST_INSERT_ID()", new MySqlParameter { ParameterName = "@UserName", Value = "test" }, new MySqlParameter { ParameterName = "@Password", Value = "aaaa" }); Console.WriteLine(id); string str = null; str.ToLower(); MySqlHelper.ExcuteNonQuery(conn, "update T_users set UserName='bbbb' where Id=10257");//必须是同一个连接conn不能忘  tx.Commit(); } catch (Exception ex) { tx.Rollback(); } }

 

------------------------------------------------
第 15 节 手机号码归属地:导入数据

手机号码归属地数据库.zip 下载地址:

1、下载地址1:http://pan.baidu.com/s/1eQETGqQ   密码:pcq7

2、下载地址2:手机号码归属地和身份证归属地数据库.zip 

 http://static.rupeng.com/upload/images/20156/BB642F2DB1F19FFB5714198BA5953E69%E6%89%8B%E6%9C%BA%E5%8F%B7%E7%A0%81%E5%BD%92%E5%B1%9E%E5%9C%B0%E5%92%8C%E8%BA%AB%E4%BB%BD%E8%AF%81%E5%BD%92%E5%B1%9E%E5%9C%B0%E6%95%B0%E6%8D%AE%E5%BA%93.zip

 项目地址:http://static.rupeng.com/upload/images/201412/AAD80266B1CD5A14E4E8B0B3C3B47F32PhoneNunArea.zip

有的学生导入数据后发现“数据库怎么只导入了1000条”,其实不是只导入了1000条,而是全部导入的,只是navicat是分页显示的,看右下角,可以翻页的。

------------------------------------------------
第 16 节 手机号码归属地的查询以及作业说明

身份证归属地数据库.zip 下载地址: 身份证所在地.zip

 

项目代码下载地址:PhoneNunArea.zip

练习:

  写一个身份证所在地查询的程序。

------------------------------------------------
第 17 节 CRUD案例之需求说明及数据查询

  人员的增删改查

  CRUD:增加(Create),读取(Retrieve),更新(Update),删除(Delete)

  (*)DataGridView的使用:把DataTable赋值给DataGridView的DataSource属性,会自动填充,不过列名都是英文,因此通过代码设置AutoGenerateColumns属性为false,然后手动增加列。列设定DataPropertyName为要显示的属性的名字,HeaderText为表头显示的文本。勾掉启用删除,启用添加,启用编辑。

     (*)增加"编辑","删除"两个列:增加“DatagridviewlinkColumn”类型的列,Text设定为"编辑"/"删除",UserColumntextForLinkValue为true,这样就把Text显示到单元格中了,否则会尝试取控件的属性,就空白了。

------------------------------------------------
第 18 节 CRUD案例之删除以及mysq的if函数

  案例:增删改查

  (*)删除点击的行:响应CellContentClick事件,e.ColumnIndex获得列号,e.RowIndex获得行号。然后:DataTable dt=(DataTable)grid.DataSource;

  DataRow=dt.Rows[e.RowIndex];

  删除之前提示一下用户,删除后刷新数据。

  性别显示为“0,1”,不好看,使用mysql的函数if:If(Gender,'男','女') Gender,mysql还有case、日期函数、字符串函数等。

------------------------------------------------
第 19 节 CRUD案例之编辑的加载

------------------------------------------------
第 20 节 CRUD案例之新增和编辑保存

项目代码下载:CRUDTest1.zip

------------------------------------------------
第 21 节 SQLServer2008R2的安装

SQLServer 2008 R2下载:

1)下载地址1:http://www.pc6.com/softview/softview_20580.html

注意:

1、SQLServer 2008 R2是SQLServer 2008的升级版,SQLServer 2008在Win7下有兼容性问题,不能运行,需要打补丁才可以。所以推荐大家装“SQLServer 2008 R2”,而不是装“SQLServer 2008”

2、大家在安装SQLServer的时候,如果跟着老师的操作安装下来还是装不上,比如如下图

如果跟同学以及学习辅导老师确认不是安装步骤的问题的话,那么很有可能是因为你使用了修改版的Windows系统(比如雨林木风、深度、电脑公司、萝卜花园等),这些修改版的Windows系统中可能一些关键性的系统组件被阉割掉了,造成SQLServer等组件安装失败。因此建议大家安装微软的原版系统。

 

3、大家用SQLServre 2005也可以,对于初学者来讲没什么差别。但是不建议大家安装SQLServer 2012、SQLServer 2014等新的版本,因为操作会和咱们讲课时候不一致。有同学会问了“不用新系统我们不就过时了吗”,我的回答:这些新版本的SQLServer的高级特性做为初学者来讲用不到,所以装上新版本装上只能“装B”用,其实学习时用的还是基础的功能,何苦呢。

4、据有同学说“SQLServer 2008 R2”在Windows 10等新系统中同样有兼容性问题,而且暂时没有解决方案。因此强烈建议各位同学不要用Windows8、Windows 10等新操作系统。这种新的操作系统出来时间不久,很多软件兼容性还不好,会浪费大家太多的时间在环境的配置、重装上,还是用Windows 7这样稳定的操作系统,节省出宝贵的时间用来学习会更好。

------------------------------------------------
第 22 节 SQLServerManagementStudio的使用

 mssql:bigit:long

 mysql:long:long

 mssql:varchar(没有中文);nvarchar(可能有中文)

 mysql:varchar

nvarchar(MAX)   GB

mssql:top (select top 20)

mysql:limit;

mssql:自动递增

mysql:是标识

保存表设计修改的时候,如果提示“不允许保存更改”:工具→选项→Designers→"阻止保存要求重新创建表的更改"。

遇到报错信息,先仔细阅读错误提示信息。

------------------------------------------------
第 23 节 ADO.Net连接SQLServer(SoEasy)

1、ADO.Net如何连接SQLServer:SQLServer驱动.Net内置(亲生的);把MySqlConnection换成SqlConnection,MySql***换成Sql***。

2、连接字符串: 

 server=ip;user id=sa;password=密码;database=db1

3、SQLHelper:把MySql查找替换成Sql就可以了。

4、获得自动增长列的值:Insert into t1(...) output inserted.Id values(.........)

5、(*)如果基于接口编程,只要改动CreateConnection就可以(查询参数以Dictionary<string,object>传递;如果使用Provider,连代码都不用改,改配置文件即可。

6、需要特别注意:SqlServer的事务和mysql事务使用有一点不一样的地方是“需要把BeginTransaction返回的SqlTransaction对象赋值给SqlCommand的Transaction属性”

 

------------------------------------------------
第 24 节 通过接口编程使用ADO.Net感受多态的强大

学完本节课后开始进行自测环节,自测完成后会组织班级讨论。题目如下:

第一题:

表一:学生表 t_student

主键Id

姓名Name

性别Gender

出生年月BirthDay

家庭住址Address

备注Remarks

1

张三

1981-8-9

北京

NULL

           
           

 

 

表二:课程表t_course

主键Id

课程名称Name

学分Score

1

计算机基础

2

2

C语言

2

 

表三:成绩表 t_grade

学生主键StudentId

课程主键CourseId

分数Score

1

1

80

1

2

90

 

题目:编写SQL语句完成下面的功能:

条件查询:

1) 在t_grade表中查找80-90分的学生Id和分数

2) 在t_grade表中查找课程Id为3学生的平均分

3) 在t_grade表中查询学习各门课程的人数

4) 查询所有姓张的学生的学号和姓名

5) 查询分数在80-90分的学生的学号、姓名、分数

6) 查询学习了’C语言’课程的学生学号、姓名和分数

 

第二题

不参考、不对照任何老师、同学的代码编写连接SQLServer数据库的SQLHelper。并记录写完需要的时间。

 

第三题

编写通讯录管理软件,有联系人列表界面、联系人新增/修改界面、还可以删除联系人。联系人有如下信息:姓名、性别、生日、手机、邮箱、通讯地址。

在“联系人列表”界面中,点击工具栏中的“导出”按钮,会弹出保存文件对话框,用户选择一个文件后,可以将所有的联系人导出到文本文件。每一行是一个联系人信息,每一行的信息为:姓名、性别、生日、手机、邮箱,各列之间用“|”分割,比如

张三|男|1992-03-05|13888888888|[email protected]

李四|女|1995-12-12|13999999999|[email protected]

 

分别用SQLServer和MYSQL实现两个版本,并不能互相拷贝代码。并记录写完两个版本各需要的时间。

 

第四题

用SQLServer重写手机号码查询归属地案例。并记录写完需要的时间。

 

------------------------------------------------

 

如鹏网:http://www.rupeng.com

你可能感兴趣的:(如鹏网.Net基础2 第七章:ADO.Net)