连接数据库代码:
private SqlConnection con = null; public void OpenConnection(string connectionString) { con = new SqlConnection(); con.ConnectionString = connectionString; con.Open(); } public void CloseConnection() { con.Close(); }
添加代码(增)
public void InsertPerson(string name, int age) { string sql = string.Format("insert into Person(Name,Age) values ('{0}',{1})", name, age); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { cmd.ExecuteNonQuery(); } }
这个方法在语法上没有问题,但你可以提供一个重载版本,允许调用者传递一个表示行数据的强类型类。
public void InsertPerson(Person p) { string sql = string.Format("insert into Person(Name,Age) values ('{0}',{1})", p.Name, p.Age); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { cmd.ExecuteNonQuery(); } }
删除代码(删)
public void DeletePerson(int id) { string sql = string.Format("Delete form Person where id={0}",id); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { try { cmd.ExecuteNonQuery(); } catch (Exception) { Console.WriteLine("删除失败"); } } }
修改代码(改)
public void UpdatePerson(int id,string name) { string sql = string.Format("Update Person set name={0} where id={1}", name,id); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { try { cmd.ExecuteNonQuery(); } catch (Exception) { Console.WriteLine("更新失败"); } } }
查询代码(查)
public List<Person> GetAllPersonList() { List<Person> list = new List<Person>(); string sql = string.Format("select * from Person"); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { SqlDataReader sr = cmd.ExecuteReader(); while (sr.Read()) { list.Add(new Person { Age=(int)sr["Age"], Name=(string)sr["Name"] }); } } return list; }
还有另一种返回System.Data.DataTable对象的方法,它实际上是ADO.NET非连接层的一部分
public DataTable GetAllPersonDataTable() { DataTable dr = new DataTable(); string sql = string.Format("select * from Person"); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { SqlDataReader sr = cmd.ExecuteReader(); dr.Load(sr); sr.Close(); } return dr; }
使用参数化的命令对象
不使用参数化的命令对象每一个 SQL 查询都是用字符串字面量硬编码的。参教化查询能像对象那样处理 SQL 参数,而不是像一堆文本一样。而且.参数化查询执行起来比纯文本的 SQL 语句快多了,它只需要解析一次(而不是像 SQL 语句那样每次被分配到CommandText 属性都要解析)。同样,参数化查询也能消除 SQL 注人攻击(非常著名的数据访问安全问题)的隐患
为支持参数化查询, ADO· NET命令对象使用一个集合来保存参数对象。这个集合默认是空的.可以添加任意多的参数对象并映射到SQL语句中的占位符参数。如果需要把 SQL 查询中的参数和命令对象参数集合中某一个成员关联的话,只需要在SQL文本参数前面加@符号(微软SQL Server是这样的,不是所有的DBMS都支持@符号)
DbParameter 类型的主要成员 | |
DbType | 从数据源获取或设置原始数据类型,以 CLR 数据类型呈现 |
Direction | 获取或设置一个值,该值指示参数是只可输入、只可输出、双向还是返回值参数 |
IsNullable | 获取或设置一个值,该值指示参数是否接受空值 |
ParameterName | 获取或设置DbParameter的名称 |
Size | 获取或设置列中数据的最大尺寸 (只对文本数据有用) |
Value | 获取或设置该参数的值 |
代码如下
public void InsertPersonPara(Person p) { string sql = string.Format("insert into Person(Name,Age) values (@Name,@Age)"); using (SqlCommand cmd = new SqlCommand(sql, this.con)) { SqlParameter param = new SqlParameter(); param.ParameterName = "@Name"; param.Value = p.Name; param.SqlDbType = SqlDbType.Char; cmd.Parameters.Add(param); param=new SqlParameter(); param.ParameterName = "@Age"; param.Value = p.Age; param.SqlDbType = SqlDbType.Int; cmd.Parameters.Add(param); }
同样,注意SQL查询包含2个嵌入的占位符,每一个都以@为前缀。使用 SqlParamter 类型,我们就可以使用 param.ParameterName属性以强类型格式来映射每一个占位符并指定各种细节(值、数据类型和大小等)。参数对象都准备好之后.就可以通过调用 Add()方法加到命令对象的集合中。
执行存储过程
存储过程是存储在数据库内的一段已命名的SQL代码,你可以构造存储过程,返回一组行或标量数据类型,或进行其他有意义的处理(如插入、更新、删除),也可以接受一些可选参数。其实它就像是一个存储在数据库内的功能模块,和那些二进制数据对象有明显区别;
public string LookUpPetName(int id) { string petName = string.Empty; using (SqlCommand cmd=new SqlCommand("GetPetName",this.con)) { cmd.CommandType = CommandType.StoredProcedure; SqlParameter param = new SqlParameter(); param.ParameterName = "@Id"; param.Value = id; param.SqlDbType = SqlDbType.Int; param.Direction = ParameterDirection.Input; cmd.Parameters.Add(param); param = new SqlParameter(); param.ParameterName = "@Name"; param.SqlDbType = SqlDbType.Char; param.Size = 20; param.Direction = ParameterDirection.Output; cmd.Parameters.Add(param); cmd.ExecuteNonQuery(); petName = (string)cmd.Parameters["@Name"].Value; } return petName; }