温故而后知新——对ado.net中常用对象的一些解释
在使用ado.net连接数据库获取数据,一般的步骤是:
1、设置好web.config //用来设置服务器数据库的地址以及登录名密码
2、创建Connection对象 //用来创建访问数据库的连接
3、创建Command对象 //用来发送命令(写sql语句)
4、用DataReader获取数据 //获取数据库数据
5、利用DataSet储存获取到的数据 //容器
6、关闭Connection对象和DataReader/DataAdapter的连接 //为了性能,不关闭可能会报错
(其中3、4两步可以用DataAdapter对象一步代替)
一、设置web.config
打开web.config,直接在根节点加入:
<connectionStrings>
<add name="Try" connectionString="data source=数据库地址;initial catalog=数据库名称;persist security info=True;user id=登录名;password=密码;"/>
</connectionStrings>
变成
<configuration> //根节点
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
<connectionStrings>
<add name="Try" connectionString="data source=数据库地址;initial catalog=数据库名称;persist security info=True;user id=登录名;password=密码;"/>
</connectionStrings>
</configuration>
这样就添加了一个连接字符串,名字叫做Try
二、Connection对象
现在要通过刚刚添加的连接字符串连接数据库了,获取web.config中的连接字符串后新建Connection对象:
using System.Configuration;
using System.Data.SqlClient; string connectionString = ConfigurationManager.ConnectionStrings["Try"].ConnectionString; //取名字为Try的连接字符串
SqlConnection conn = new SqlConnection(connectionString); //用这个连接字符串新建Connection对象
三、Command对象
在使用Command对象之前,必须保证我们的Connection对象已经处于open状态:
conn.Open();
Commond对象的创建,无论用哪种形式,只要保证它与Connection对象的联系以及我们写的sql语句传进去了就行:
SqlCommand cmd = conn.CreateCommand(); //通过之前的Connection对象创建
cmd.CommandText = "select top 10 * from Project"; //写sql语句 //或者下面的直接构造函数的形式 SqlCommand sc = new SqlCommand("select top 10 * from Project", conn);
它有三个常用方法
1.ExecuteNonQuery(); 该方法适用于非查询语句,返回受影响的行数(int)
cmd.CommandText = "update Project set Name='tom' where id=3";
int result = cmd.ExecuteNonQuery(); //返回1,即有一条数据被修改
2.ExecuteScalar(); 该方法返回查询结果的第一行第一列数据(object)
cmd.CommandText = "select count(*) from Project";
int result = int.Parse( cmd.ExecuteScalar() ); //返回Project表的总行数,由于返回类型是object,因此需要转换成int
3.ExecuteReader(); 该方法返回一个DataReader对象,用于获取查询的结果,后面详解
四、DataReader对象和DataAdapter对象
1.DataReader的用法
DataReader可以通过Command的ExecuteReader()方法返回,它的核心方法是Read():
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read()) //Read方法返回一个bool值,如果有值就返回true并前进到下一行,当整个表读取结束了就返回false
{
Response.Write(dr.GetInt32()); //这里假设表的第一列是int型,GetInt32()方法需要传一个int参数,从0开始的列的索引值
}
这样把查询结果的第一列就读取出来的,它适合快速获取一些信息
读取完之后记得关闭DataReader:
dr.Close();
dr.Dispose();
2.DataAdapter的用法
DataAdapter对象也称之为数据适配器对象,用来填充一个DataSet容器:
DataSet a=new DataSet("ds1");
SqlDataAdapter ada = new SqlDataAdapter("select top 10 * from Project", conn);
ada.Fill(a);
注:
在用完后记得要关闭Connection和DataReader/DataAdapter:
ada.Dispose();
dr.Dispose();
conn.Close();
conn.Dispose();
这其实很麻烦,用完了还得关闭,为了图简便,可以使用using语法。
其完整的读取数据并返回DataSet示例如下:
static public DataSet FillDataSet(string sql,params SqlParameter[] paras)
{
string connectionString = ConfigurationManager.ConnectionStrings["Try"].ConnectionString; //取名字为Try的连接字符串
DataSet ds = new DataSet("ds1");
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlDataAdapter ada = new SqlDataAdapter(sql, conn))
{
ada.SelectCommand.Parameters.AddRange(paras);//传参
ada.Fill(ds);
}
}
return ds;
}
另附上完整的ExecuteNonQuery方法:
static public int ExecuteNonQuery(string sql, params SqlParameter[] paras)
{
int result = ;
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(paras); //传参
result = cmd.ExecuteNonQuery();
}
return result;
}
注:加了params的参数表示可以不写,即不需要传null,直接ExecuteNonQuery(string sql) 就行了
2014-12-29新增
近日感觉调用的时候有点麻烦,每次传参都需要new SqlParameter[]{new SqlParameter(){ParameterName = name, Value = val}} ; 于是将整个DBHelper类改写成如下形式:
public class DBHelper
{
static string connectionString = ConfigurationManager.ConnectionStrings["Try"].ConnectionString;
static public DataSet FillDataSet(string sql, object paras)
{
DataSet a = new DataSet();
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlDataAdapter ada = new SqlDataAdapter(sql, conn);
ada.SelectCommand.Parameters.AddRange(GetParas(paras));
ada.Fill(a);
}
return a;
}
static public List<T> FillList<T>(string sql, object paras)
{
DataSet a = new DataSet();
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlDataAdapter ada = new SqlDataAdapter(sql, conn);
ada.SelectCommand.Parameters.AddRange(GetParas(paras));
ada.Fill(a);
}
return DataSetToList<T>(a, ).ToList();
}
static public int ExecuteNonQuery(string sql, object paras)
{
int result = ;
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(GetParas(paras));
result = cmd.ExecuteNonQuery();
}
return result;
}
static public object ExecuteScalar(string sql, object paras)
{
object result = ;
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(GetParas(paras));
result = cmd.ExecuteScalar();
}
return result;
} /// <summary>
/// DataSetToList
/// </summary>
/// <typeparam name="T">转换类型</typeparam>
/// <param name="dataSet">数据源</param>
/// <param name="tableIndex">需要转换表的索引</param>
/// <returns></returns>
private static IList<T> DataSetToList<T>(DataSet dataSet, int tableIndex)
{
//确认参数有效
if (dataSet == null || dataSet.Tables.Count <= || tableIndex < )
return null; DataTable dt = dataSet.Tables[tableIndex]; IList<T> list = new List<T>(); for (int i = ; i < dt.Rows.Count; i++)
{
//创建泛型对象
T _t = Activator.CreateInstance<T>();
//获取对象所有属性
PropertyInfo[] propertyInfo = _t.GetType().GetProperties();
for (int j = ; j < dt.Columns.Count; j++)
{
foreach (PropertyInfo info in propertyInfo)
{
//属性名称和列名相同时赋值
if (dt.Columns[j].ColumnName.ToUpper().Equals(info.Name.ToUpper()))
{
if (dt.Rows[i][j] != DBNull.Value)
{
info.SetValue(_t, dt.Rows[i][j], null);
}
else
{
info.SetValue(_t, null, null);
}
break;
}
}
}
list.Add(_t);
}
return list;
}
private static SqlParameter[] GetParas(object paras)
{
if (paras != null)
{
List<SqlParameter> list = new List<SqlParameter>();
Type t = paras.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{ string name = pi.Name;
object val = pi.GetValue(paras, null);
list.Add(new SqlParameter() { ParameterName = name, Value = val });
}
return list.ToArray();
}
else
{
return new SqlParameter[];
}
}
}
调用的时候就不必再new一个SqlParameterp[]数组了,可以直接
int id = , fid = ;
string sql = "select * from tb where id=@userID and uId=@uId";
DataSet ds = DBHelper.FillDataSet(sql,new { userID = id , uId=fid });
传参就简单多了。缺陷是无法使用params关键字了,params关键字只能修饰一维数组。所以没有参数的时候也记得写个null,例:
string sql = "select * from tb";
DataSet ds = DBHelper.FillDataSet(sql,null);
2016-11-17新增
增加对事务的支持,整个类代码如下:
public class DbHelper
{
#region 静态
private static string ConnStr { get; set; }//静态类的连接字符串,后面的实例统一调用这个连接字符串
/// <summary>
/// 设置连接字符串
/// </summary>
/// <param name="connStr"></param>
public static void SetConnectionString(string connStr)
{
DbHelper.ConnStr = connStr;
}
/// <summary>
/// 将object转换成SqlParameter[]
/// </summary>
/// <param name="paras"></param>
/// <returns></returns>
private static SqlParameter[] ConvertToSqlParameter(object paras)
{
List<SqlParameter> list = new List<SqlParameter>();
if (paras != null)
{
Type t = paras.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{ string name = pi.Name;
object val = pi.GetValue(paras, null);
list.Add(new SqlParameter() { ParameterName = name, Value = val });
}
}
return list.ToArray();
}
#endregion //*****************非静态******************* #region 基本属性
private SqlConnection _conn;
protected SqlConnection conn
{
get
{
if (_conn == null)
{
_conn = new SqlConnection();
}
return _conn;
}
}
private SqlCommand _cmd;
protected SqlCommand cmd
{
get
{
if (_cmd == null)
{
_cmd = new SqlCommand();
_cmd.Connection = conn;//设置cmd对象的conn
}
return _cmd;
}
}
private SqlDataAdapter _adapter;
protected SqlDataAdapter adapter
{
get
{
if (_adapter == null)
{
_adapter = new SqlDataAdapter();
}
return _adapter;
}
}
protected SqlTransaction trans { get; set; }
private bool IsTrans { get; set; }//是否事务
#endregion #region 构造函数
public DbHelper()
{ }
#endregion #region 打开或关闭连接对象
/// <summary>
/// 打开连接,如果已经打开则什么都不执行了
/// </summary>
private void OpenConnection()
{
if (this.conn.State != ConnectionState.Open)
{
this.conn.ConnectionString = DbHelper.ConnStr;
this.conn.Open();
}
}
/// <summary>
/// 关闭连接,如果没有开始事务或连接打开时才关闭
/// </summary>
private void CloseConnect()
{
if (!this.IsTrans)
{
if (this.conn.State == ConnectionState.Open)
{
this.conn.Close();
this.conn.Dispose();
}
}
}
/// <summary>
/// 给当前DbCommand对象赋值,并且OpenConnection();
/// </summary>
private void OpenConnectAndSetCommand(string sqlText, CommandType cmdType, object param)
{
OpenConnection();
this.cmd.Parameters.Clear();
if (param != null)
{
this.cmd.Parameters.AddRange(DbHelper.ConvertToSqlParameter(param));
}
this.cmd.CommandText = sqlText;
this.cmd.CommandType = cmdType;
}
#endregion #region 执行sql的基本方法
/// <summary>
/// 执行查询,并返回查询结果的第一行第一列
/// </summary>
/// <param name="sqlText"></param>
/// <param name="cmdType"></param>
/// <param name="param"></param>
/// <returns></returns>
public object ExecuteScalar(string sqlText, object param = null, CommandType cmdType = CommandType.Text)
{
try
{
OpenConnectAndSetCommand(sqlText, cmdType, param);
return this.cmd.ExecuteScalar(); }
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}
public object ExecuteScalar(string sqlText, CommandType cmdType)
{
return ExecuteScalar(sqlText, null, cmdType);
} /// <summary>
/// 执行非查询语句,并返回受影响的行数
/// </summary>
/// <param name="sqlText"></param>
/// <param name="cmdType"></param>
/// <param name="param"></param>
/// <returns></returns>
public int ExecuteNonQuery(string sqlText, object param = null, CommandType cmdType = CommandType.Text)
{
try
{
OpenConnectAndSetCommand(sqlText, cmdType, param);
return this.cmd.ExecuteNonQuery(); }
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}
public int ExecuteNonQuery(string sqlText, CommandType cmdType)
{
return ExecuteNonQuery(sqlText, null, cmdType);
}
/// <summary>
/// 返回DataSet
/// </summary>
/// <param name="sqlText"></param>
/// <param name="cmdType"></param>
/// <param name="param"></param>
/// <returns></returns>
public DataSet GetDataSet(string sqlText, object param = null, CommandType cmdType = CommandType.Text)
{
try
{
OpenConnectAndSetCommand(sqlText, cmdType, param);
adapter.SelectCommand = this.cmd;
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}
public DataSet GetDataSet(string sqlText, CommandType cmdType)
{
return GetDataSet(sqlText, null, cmdType);
} /// <summary>
/// 返回DataTable
/// </summary>
/// <param name="sqlText"></param>
/// <param name="cmdType"></param>
/// <param name="param"></param>
/// <returns></returns>
public DataTable GetDataTable(string sqlText, object param = null, CommandType cmdType = CommandType.Text)
{
try
{
OpenConnectAndSetCommand(sqlText, cmdType, param);
adapter.SelectCommand = this.cmd;
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds.Tables[];
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}
public DataTable GetDataTable(string sqlText, CommandType cmdType)
{
return GetDataTable(sqlText, null, cmdType);
}
#endregion #region 关于事务的方法
/// <summary>
/// 开始执行事务
/// </summary>
public void TransBegin()
{
OpenConnection();
this.IsTrans = true;
this.trans = this.conn.BeginTransaction();
cmd.Transaction = this.trans;
}
/// <summary>
/// 事务提交
/// </summary>
public void TransCommit()
{
this.trans.Commit();
this.IsTrans = false;
CloseConnect();
}
/// <summary>
/// 事务回滚
/// </summary>
public void TransRollback()
{
this.trans.Rollback();
this.IsTrans = false;
CloseConnect();
}
#endregion }
调用方法:
string connStr = ConfigurationManager.ConnectionStrings["MyDapper"].ConnectionString;
DbHelper.SetConnectionString(connStr);//注册连接字符串 DbHelper db = new DbHelper(); db.TransBegin(); string sql="select * from Tcar where id=1";
var result = db.GetDataTable(sql); db.TransCommit();
温故而后知新——对ado.net中常用对象的一些解释的更多相关文章
- ADO.net中常用的对象有哪些?
ADO.net中常用的对象有哪些?分别描述一下. 答:Connection 数据库连接对像 Command 数据库命令 DataReader 数据读取器 DataSet 数据集 DataReader与 ...
- ADO.NET中COMMAND对象的ExecuteNonQuery、ExcuteReader和ExecuteScalar方法
1.ExecuteNonQuery方法.该方法执行更新操作,即与UPDATE.INSERT.DELETE等语句有关的操作,在这种情况下,返回值是命令影响的行数.对其他语句,如SET或CREATE,则返 ...
- 洗礼灵魂,修炼python(18)--温故加知新
类型转换: 1.str(),repr(),format():将非字符串数据转换为字符串 str():对象序列化的结果,相当于print输出 repr():程序中某个对象精确值 format():利用特 ...
- ADO.net中常用的对象介绍
ADO.NET的对象主要包括:DataSet,DataTable,DataColumn,DataRow,和DataRelation. DataSet:这个对象是一个集合对象,它可以包含任意数量的数据表 ...
- ADO.NET中主要对象
ADO.NET是什么? ADO.NET是.Net平台提供和数据库交互的类库集,我们可以通过它对SQLSERVER,XML,Oracle等这样的数据源进行访问. 应用程序可以使用ADO.NET链接到数据 ...
- 已知前序(后序)遍历序列和中序遍历序列构建二叉树(Leetcode相关题目)
1.文字描述: 已知一颗二叉树的前序(后序)遍历序列和中序遍历序列,如何构建这棵二叉树? 以前序为例子: 前序遍历序列:ABCDEF 中序遍历序列:CBDAEF 前序遍历先访问根节点,因此前序遍历序列 ...
- [转帖]知新之--12-factors
知新之--12-factors https://blog.csdn.net/weixin_34233421/article/details/85819756 12-factors I. 基准代码 一份 ...
- .net 知新:【4】NuGet简介和使用
在包管理以前我们在项目中引用第三方包通常是去下载dll放到项目中再引用,后来逐渐发展成各种包管理工具,nuget就是一种工具,适用于任何现代开发平台的基本工具可充当一种机制,通过这种机制,开发人员可以 ...
- 黑马程序员_Java基础:JDK1.5后的新特性:自动拆装箱,以及注意事项
------- android培训.java培训.期待与您交流! ---------- 首先来看一段代码: Integer x = new Integer(4); Integer y = 4; 在JD ...
随机推荐
- [Redmine] Centos5上安装Redmine3.0+nginx+thin部署
项目管理的需要所以安装Redmine,其实wiki放在上面也不错的. 首先是安装,ruby应用第一次装,把坑记住. nginx, mysql是已经安装好的,只需要配置, 结合nginx的部署方式很多, ...
- UE4 射线拾取&三维画线
虽然有人建议UE4使用C++创建VR项目,能避免一些坑爹的错误,但是我用C++创建,竟然问题更多,还存在创建不了的情况,也不知道是不是我的操作问题,快疯了. 于是我还是选择了蓝图创建VR项目,但是.. ...
- 我眼中的Linux设备树(一 概述)
一 概述设备树(Device tree)是一套用来描述硬件属相的规则.ARM Linux采用设备树机制源于2011年3月份Linux创始人Linus Torvalds发的一封邮件,在这封邮件中他提倡A ...
- 【Android 系统开发】 Android 系统启动流程简介
作者 : 万境绝尘 (octopus_truth@163.com) 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/3889548 ...
- (NO.00003)iOS游戏简单的机器人投射游戏成形记(十四)
我们首先必须将Level中所有机器人保存在某个数组里,因为该数组会在不同地方被访问,我们将其放在LevelRestrict类中,按道理应该放到GameState类中,这里从简. 打开LevelRest ...
- OJ题:奇偶归一猜想——求归一过程中的最大值
题目: 题目内容: 奇偶归一猜想--对于每一个正整数,如果它是奇数,则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1. 如n = 11,得序列:11, 34, 17, 52, ...
- iOS屏幕适配-iOS笔记
学习目标 1.[了解]屏幕适配的发展史 2.[了解]autoResizing基本用法 3.[掌握]autoLayout 的基本用法 4.[掌握]autoLayout代码实现 5.[理解]sizeCla ...
- 10、Libgdx的内存管理
(官网:www.libgdx.cn) 游戏是非常耗资源的应用.图片和音效可能耗费大量的内存,另一方面来说,这些资源没有被Java垃圾回收,让一个垃圾处理来决定将显存中的5M的图片进行释放也不是一个明知 ...
- H5学习之旅-H5与Php交互(12)
1.首先介绍PHP开发环境的搭建 ,在Google搜apachefriends,会有xampp的下载链接,这个工具集成了apache的很多服务 2.搭建php的编辑环境,选取eclipse安装php插 ...
- 如何设计一个web容器
开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探 ...