ado.net快速上手实践篇(一)

 

文章来源:IT工程信息网  http://www.systhinker.com/?viewnews-11675

前言:这两天重温经典,对ado.net的东西稍微深入的了解了一下,顺便写点代码练练手,全当是复习笔记吧。
一、简单说说ado.net的5大常用对象

既然说ado.net,当然不能免俗地要提到5大常用对象。本文不会对ado.net的5大对象和它们的关系进行过多阐释,不过我们应该对下面这张图的结构有个了解:

关于上图图示中的5大对象,经常做以数据为驱动的mis系统的童鞋应该不会陌生。本文一笔带过。下面我们一步一步实现以ado.net为核心的数据访问程序。

注意:下面的示例代码和demo是楼猪本周六和周日两天时间实现的,未经详细测试,可能有重大bug,下载学习使用的童鞋务必注意】

二、数据访问持久化层
1、IDbOperation接口

代码
using  System.Collections.Generic;
using  System.Data;
using  System.Data.Common;

namespace  AdoNetDataAccess.Core.Contract
{
    
public   interface  IDbOperation
    {
        DbCommand CreateDbCommd(DbConnection sqlConn, DbTransaction transaction, 
string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        DbParameter CreateDbPrameter(
string  paramName,  object  paramValue);

        DbDataReader ExecuteReader(
string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        DataTable FillDataTable(
string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        DataSet FillDataSet(
string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        
object  ExecuteScalar( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        
int  ExecuteNonQuery( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams);

        
///   <summary>
        
///  批量插入
        
///   </summary>
        
///   <param name="tableName"> 表名称 </param>
        
///   <param name="dt"> 组装好的要批量导入的datatable </param>
        
///   <returns></returns>
         bool  ExecuteBatchInsert( string  tableName,  int  batchSize,  int  copyTimeout, DataTable dt);

        
void  OpenConnection();

        
void  CloseConnection();
    }
}

上面的接口包括增删改查,批量插入以及数据库连接对象的连接和关闭等常用操作,您可以根据命名和参数轻松理解函数的含义。根据楼猪的开发经验,对于平时的数据库操作,上述方法差不多够用了。当然您也可以按照自己需要,重写组织添加其他函数。
2、针对一种数据源的数据操作实现
底层的数据操作接口定义好后,就要针对一种数据源,具体实现上述的数据操作。这里楼猪选择了Sql Server。我们也可以实现其他数据源的数据访问操作,按照配置,利用抽象工厂动态反射选择是哪一种数据源的实现。这里按下不表,有心的童鞋自己可以动手一试。下面是具体的实现:

代码
using  System;
using  System.Collections.Generic;
using  System.Data;
using  System.Data.Common;
using  System.Data.SqlClient;
using  System.Transactions;

namespace  AdoNetDataAccess.Core.Implement
{
    
using  AdoNetDataAccess.Core.Contract;

    
public   class  SqlServer : IDbOperation, IDisposable
    {
        
private   int  cmdTimeOut  =   60 ;
        
private  DbConnection sqlConn  =   null ;
        
private  DbCommand cmd  =   null ;

        
private  SqlServer()
        {

        }

        
public  SqlServer( string  sqlConStr)
        {
            sqlConn 
=   new  SqlConnection(sqlConStr);
            cmdTimeOut 
=  sqlConn.ConnectionTimeout;
        }

        
public  SqlServer( string  sqlConStr,  int  timeOut)
        {
            sqlConn 
=   new  SqlConnection(sqlConStr);
            
if  (timeOut  <   0 )
            {
                timeOut 
=  sqlConn.ConnectionTimeout;
            }
            cmdTimeOut 
=  timeOut;
        }

        
#region  contract method

        
public  DbCommand CreateDbCommd(DbConnection sqlConn, DbTransaction transaction,  string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            DbCommand cmd 
=   new  SqlCommand();
            cmd.Connection 
=  sqlConn;
            cmd.CommandText 
=  sqlStr;
            cmd.CommandType 
=  cmdType;
            
if  (transaction  !=   null )
            {
                cmd.Transaction 
=  transaction;
            }
            
if  (listParams  !=   null   &&  listParams.Count  >   0 )
            {
                cmd.Parameters.AddRange(listParams.ToArray());
            }
            cmd.CommandTimeout 
=  cmdTimeOut;
            OpenConnection();
            
return  cmd;
        }

        
public  DbParameter CreateDbPrameter( string  paramName,  object  paramValue)
        {
            SqlParameter sp 
=   new  SqlParameter(paramName, paramValue);
            
return  sp;
        }

        
public  DbDataReader ExecuteReader( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            DbDataReader rdr 
=   null ;
            
try
            {
                OpenConnection();
                cmd 
=  CreateDbCommd(sqlConn,  null , sqlStr, cmdType, listParams);
                rdr 
=  cmd.ExecuteReader();
            }
            
catch  (Exception ex)
            {
                
throw  ex;
            }
            
return  rdr;
        }

        
public  DataTable FillDataTable( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            OpenConnection();
            DbTransaction trans 
=  sqlConn.BeginTransaction();
            DbCommand cmd 
=  CreateDbCommd(sqlConn, trans, sqlStr, cmdType, listParams);
            SqlDataAdapter sqlDataAdpter 
=   new  SqlDataAdapter(cmd  as  SqlCommand);
            DataTable dt 
=   new  DataTable();
            
try
            {
                sqlDataAdpter.Fill(dt);
                trans.Commit();
            }
            
catch  (Exception e)
            {
                trans.Rollback();
                
throw   new  Exception( " 执行数据库操作失败, sql:  "   +  sqlStr, e);
            }
            
finally
            {
                sqlDataAdpter.Dispose();
                cmd.Dispose();
                trans.Dispose();
                CloseConnection();
            }
            
return  dt;
        }

        
public  DataSet FillDataSet( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            OpenConnection();
            DbTransaction trans 
=  sqlConn.BeginTransaction();
            DbCommand cmd 
=  CreateDbCommd(sqlConn, trans, sqlStr, cmdType, listParams);
            SqlDataAdapter sqlDataAdpter 
=   new  SqlDataAdapter(cmd  as  SqlCommand);
            DataSet ds 
=   new  DataSet();
            
try
            {
                sqlDataAdpter.Fill(ds);
                trans.Commit();
            }
            
catch  (Exception e)
            {
                trans.Rollback();
                
throw   new  Exception( " 执行数据库操作失败, sql:  "   +  sqlStr, e);
            }
            
finally
            {
                sqlDataAdpter.Dispose();
                cmd.Dispose();
                trans.Dispose();
                CloseConnection();
            }
            
return  ds;
        }

        
public   object  ExecuteScalar( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            
object  result  =   null ;
            OpenConnection();
            DbTransaction trans 
=  sqlConn.BeginTransaction();
            
try
            {
                cmd 
=  CreateDbCommd(sqlConn, trans, sqlStr, cmdType, listParams);
                result 
=  cmd.ExecuteScalar();
                trans.Commit();
            }
            
catch  (Exception e)
            {
                trans.Rollback();
                
throw   new  Exception( " 执行数据库操作失败, sql:  "   +  sqlStr, e);
            }
            
finally
            {
                trans.Dispose();
                CloseConnection();
            }
            
return  result;
        }

        
public   int  ExecuteNonQuery( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams)
        {
            
int  result  =   - 1 ;
            OpenConnection();
            DbTransaction trans 
=  sqlConn.BeginTransaction();
            
try
            {
                cmd 
=  CreateDbCommd(sqlConn, trans, sqlStr, cmdType, listParams);
                result 
=  cmd.ExecuteNonQuery();
                trans.Commit();
            }
            
catch  (Exception e)
            {
                trans.Rollback();
                
throw   new  Exception( " 执行数据库操作失败, sql:  "   +  sqlStr, e);
            }
            
finally
            {
                trans.Dispose();
                CloseConnection();
            }
            
return  result;
        }

        
///   <summary>
        
///  批量插入
        
///   </summary>
        
///   <param name="tableName"></param>
        
///   <param name="batchSize"></param>
        
///   <param name="copyTimeout"></param>
        
///   <param name="dt"></param>
        
///   <returns></returns>
         public   bool  ExecuteBatchInsert( string  tableName,  int  batchSize,  int  copyTimeout, DataTable dt)
        {
            
bool  flag  =   false ;
            
try
            {
                
using  (TransactionScope scope  =   new  TransactionScope())
                {
                    OpenConnection();
                    
using  (SqlBulkCopy sbc  =   new  SqlBulkCopy(sqlConn  as  SqlConnection))
                    {
                        
// 服务器上目标表的名称
                        sbc.DestinationTableName  =  tableName;
                        sbc.BatchSize 
=  batchSize;
                        sbc.BulkCopyTimeout 
=  copyTimeout;
                        
for  ( int  i  =   0 ; i  <  dt.Columns.Count; i ++ )
                        {
                            
// 列映射定义数据源中的列和目标表中的列之间的关系
                            sbc.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
                        }
                        sbc.WriteToServer(dt);
                        flag 
=   true ;
                        scope.Complete();
// 有效的事务
                    }
                }
            }
            
catch  (Exception ex)
            {
                
throw  ex;
            }
            
return  flag;
        }

        
public   void  OpenConnection()
        {
            
if  (sqlConn.State  ==  ConnectionState.Broken  ||  sqlConn.State  ==  ConnectionState.Closed)
                sqlConn.Open();
        }

        
public   void  CloseConnection()
        {
            sqlConn.Close();
        }

        
#endregion

        
#region  dispose method

        
///   <summary>
        
///  dispose接口方法
        
///   </summary>
         public   void  Dispose()
        {

        }

        
#endregion
    }
}

到这里,我们实现了SqlServer类里的方法,对Ms SqlServer数据库我们就已经可以进行简单的基础的CRUD操作了。

三、简单直观的对象实体转换
在第二步中,我们已经实现了简单的数据CRUD操作。根据楼猪使用ORM的经验和习惯,我们也应该对一些查询结果进行转换,因为以类的组织方式比直接呈现ado.net对象更容易让人接受,效率高低反在其次。下面利用常见的反射原理,简单实现一个对象实体转换器ModelConverter类:

代码
using  System;
using  System.Collections;
using  System.Collections.Generic;
using  System.Data;
using  System.Data.Common;
using  System.Reflection;
using  System.Threading;

namespace  AdoNetDataAccess.Core.Obj2Model
{
    
using  AdoNetDataAccess.Core.Contract;

    
public   sealed   class  ModelConverter
    {
        
private   static   readonly   object  objSync  =   new   object ();

        
#region  query for list

        
///   <summary>
        
///  查询数据表项并转换为对应实体
        
///   </summary>
        
///   <typeparam name="T"></typeparam>
        
///   <param name="objType"></param>
        
///   <param name="rdr"></param>
        
///   <returns></returns>
         public   static  IList < T >  QueryForList < T > ( string  sqlStr, CommandType cmdType, List < DbParameter >  listParams, Type objType, IDbOperation dbOperation)
            
where  T :  class new ()
        {
            IDataReader rdr 
=  dbOperation.ExecuteReader(sqlStr, cmdType, listParams);
            IList
< T >  listModels  =   new  List < T > ();
            
try
            {
                Monitor.Enter(objSync);
                Hashtable ht 
=  CreateHashColumnName(rdr);
                
while  (rdr.Read())
                {
                    Object obj 
=  Activator.CreateInstance(objType);
                    PropertyInfo[] properties 
=  objType.GetProperties();
                    
foreach  (PropertyInfo propInfo  in  properties)
                    {
                        
string  columnName  =  propInfo.Name.ToUpper();
                        
if  (ht.ContainsKey(columnName)  ==   false )
                        {
                            
continue ;
                        }
                        
int  index  =  rdr.GetOrdinal(propInfo.Name);
                        
object  columnValue  =  rdr.GetValue(index);
                        
if  (columnValue  !=  System.DBNull.Value)
                        {
                            SetValue(propInfo, obj, columnValue);
                        }
                    }
                    T model 
=   default (T);
                    model 
=  obj  as  T;
                    listModels.Add(model);
                }
            }
            
finally
            {
                rdr.Close();
                rdr.Dispose();
                Monitor.Exit(objSync);
            }
            
return  listModels;
        }

        
#endregion

        
#region  query for dictionary

        
///   <summary>
        
///  查询数据表项并转换为对应实体
        
///   </summary>
        
///   <typeparam name="K"></typeparam>
        
///   <typeparam name="T"></typeparam>
        
///   <param name="key"> 字典对应key列名 </param>
        
///   <param name="objType"></param>
        
///   <param name="rdr"></param>
        
///   <returns></returns>
         public  
 
文章来源:IT工程信息网  http://www.systhinker.com/?viewnews-11675
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值