zoukankan      html  css  js  c++  java
  • DataAccess通用数据库访问类,简单易用,功能强悍

    以下是我编写的DataAccess通用数据库访问类,简单易用,支持:内联式创建多个参数、支持多事务提交、支持参数复用、支持更换数据库类型,希望能帮到大家,若需支持查出来后转换成实体,可以自行扩展datarow转实体类,也可以搭配dapper.net实现更强大的功能。

        /// <summary>
        /// 通用数据库访问类,支持多种数据库,无直接依赖某个数据库组件
        /// 作者:左文俊
        /// 日期:2016-6-3(修订:2017-6-1)
        /// </summary>
        public class DataAccess : IDisposable
        {
            [ThreadStatic]
            private static DbProviderFactory _dbProviderFactory = null;
    
            [ThreadStatic]
            private static string _connectionString = string.Empty;
    
            [ThreadStatic]
            public static string ConnectionStringName = string.Empty;
    
            private DbProviderFactory dbProviderFactory = null;
            private string connectionString = string.Empty;
    
            private DbConnection dbConnection = null;
            private DbTransaction dbTransaction = null;
            private bool useTransaction = false;
            private bool disposed = false;
            private bool committed = false;
    
            private ParameterHelperClass paramHelper = null;
    
            public DataAccess()
                : this("default")
            { }
    
            public DataAccess(string cnnStringName, Func<string, string> DecryptCnnStringFunc = null)
            {
                if (!string.Equals(ConnectionStringName, cnnStringName, StringComparison.OrdinalIgnoreCase) ||
                    _dbProviderFactory == null || _connectionString == null)
                {
                    ConnectionStringName = cnnStringName;
                    var cnnStringSection = ConfigurationManager.ConnectionStrings[cnnStringName];
                    _dbProviderFactory = DbProviderFactories.GetFactory(cnnStringSection.ProviderName);
                    _connectionString = cnnStringSection.ConnectionString;
                    if (DecryptCnnStringFunc != null)
                    {
                        _connectionString = DecryptCnnStringFunc(_connectionString);
                    }
                }
                dbProviderFactory = _dbProviderFactory;
                connectionString = _connectionString;
    
                paramHelper = new ParameterHelperClass(this);
            }
    
            public DataAccess(string cnnString, string providerName)
            {
                if (!string.Equals(_connectionString, cnnString, StringComparison.OrdinalIgnoreCase) || _dbProviderFactory == null)
                {
                    ConnectionStringName = string.Empty;
                    _connectionString = cnnString;
                    _dbProviderFactory = DbProviderFactories.GetFactory(providerName);
                }
                dbProviderFactory = _dbProviderFactory;
                connectionString = _connectionString;
    
                paramHelper = new ParameterHelperClass(this);
            }
    
    
            #region 私有方法
    
            private DbConnection GetDbConnection()
            {
    
                if (dbConnection == null)
                {
                    dbConnection = dbProviderFactory.CreateConnection();
                    dbConnection.ConnectionString = connectionString;
                }
    
                if (dbConnection.State == ConnectionState.Closed)
                {
                    dbConnection.Open();
                }
    
                if (useTransaction && dbTransaction == null)
                {
                    dbTransaction = dbConnection.BeginTransaction();
                    committed = false;
                }
    
                return dbConnection;
            }
    
    
    
            private DbCommand BuildDbCommand(string sqlCmdText, CommandType cmdType = CommandType.Text, DbParameter[] parameters = null)
            {
                var dbCmd = dbProviderFactory.CreateCommand();
                var dbConn = GetDbConnection();
                dbCmd.Connection = dbConn;
                dbCmd.CommandText = sqlCmdText;
                dbCmd.CommandType = cmdType;
                dbCmd.CommandTimeout = 30 * 60;
                if (useTransaction)
                {
                    dbCmd.Transaction = dbTransaction;
                }
    
                if (parameters != null)
                {
                    dbCmd.Parameters.AddRange(parameters);
                }
    
                return dbCmd;
            }
    
            private DbCommand BuildDbCommand(string sqlCmdText, CommandType cmdType = CommandType.Text, IDictionary<string, object> paramNameValues = null)
            {
                List<DbParameter> parameters = new List<DbParameter>();
                if (paramNameValues != null)
                {
                    foreach (var item in paramNameValues)
                    {
                        parameters.Add(BuildDbParameter(item.Key, item.Value));
                    }
                }
                return BuildDbCommand(sqlCmdText, cmdType, parameters.ToArray());
            }
    
    
    
    
            private DbCommand BuildDbCommand(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                if (paramObjs != null && paramObjs.Length > 0)
                {
                    if (paramObjs[0] is IDictionary<string, object>)
                    {
                        return BuildDbCommand(sqlCmdText, cmdType, paramObjs[0] as IDictionary<string, object>);
                    }
                    else if (paramObjs is DbParameter[])
                    {
                        return BuildDbCommand(sqlCmdText, cmdType, paramObjs as DbParameter[]);
                    }
                    else
                    {
                        List<DbParameter> parameters = new List<DbParameter>();
                        for (int i = 0; i < paramObjs.Length; i++)
                        {
                            parameters.Add(BuildDbParameter("@p" + i.ToString(), paramObjs[i]));
                        }
                        return BuildDbCommand(sqlCmdText, cmdType, parameters.ToArray());
                    }
                }
                else
                {
                    return BuildDbCommand(sqlCmdText, cmdType, parameters: null);
                }
            }
    
    
            private void ClearCommandParameters(DbCommand cmd)
            {
                bool canClear = true;
                if (cmd.Connection != null && cmd.Connection.State != ConnectionState.Open)
                {
                    foreach (DbParameter commandParameter in cmd.Parameters)
                    {
                        if (commandParameter.Direction != ParameterDirection.Input)
                        {
                            canClear = false;
                            break;
                        }
                    }
                }
                if (canClear)
                {
                    cmd.Parameters.Clear();
                }
            }
    
    
            #endregion
    
            #region 公共方法
    
            public void UseTransaction()
            {
                useTransaction = true;
            }
    
    
            public void Commit()
            {
                if (dbTransaction != null && useTransaction)
                {
                    dbTransaction.Commit();
                    dbTransaction.Dispose();
                    dbTransaction = null;
                    committed = true;
                    useTransaction = false;
                }
            }
    
    
            public DbParameter BuildDbParameter(string name, object value)
            {
                DbParameter parameter = dbProviderFactory.CreateParameter();
                parameter.ParameterName = name;
                parameter.Value = value != null ? value : DBNull.Value;
                return parameter;
            }
    
            public DbParameter BuildDbParameter(string name, object value, DbType dbType, int size = -1, ParameterDirection direction = ParameterDirection.Input)
            {
                DbParameter parameter = dbProviderFactory.CreateParameter();
                parameter.ParameterName = name;
                parameter.Value = value != null ? value : DBNull.Value;
                parameter.DbType = dbType;
                parameter.Direction = direction;
                if (size != -1)
                {
                    parameter.Size = size;
                }
                return parameter;
            }
    
            public DbParameter BuildDbParameter(string name, DbType dbType, string srcColumn, int size = -1, bool srcColumnNullMapping = true, ParameterDirection direction = ParameterDirection.Input)
            {
                DbParameter parameter = dbProviderFactory.CreateParameter();
                parameter.ParameterName = name;
                parameter.SourceColumn = srcColumn;
                parameter.SourceColumnNullMapping = srcColumnNullMapping;
                parameter.DbType = dbType;
                parameter.Direction = direction;
                if (size != -1)
                {
                    parameter.Size = size;
                }
                return parameter;
            }
    
            public DbDataReader ExecuteReader(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                var dbCmd = BuildDbCommand(sqlCmdText, cmdType, paramObjs);
                var dr = dbCmd.ExecuteReader();
                ClearCommandParameters(dbCmd);
                return dr;
            }
    
    
            public T ExecuteScalar<T>(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                T returnValue = default(T);
                var dbCmd = BuildDbCommand(sqlCmdText, cmdType, paramObjs);
                object result = dbCmd.ExecuteScalar();
                try
                {
                    returnValue = (T)Convert.ChangeType(result, typeof(T));
                }
                catch
                { }
                ClearCommandParameters(dbCmd);
                return returnValue;
            }
    
            public DataSet ExecuteDataSet(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                var dbCmd = BuildDbCommand(sqlCmdText, cmdType, paramObjs);
                var dbAdapter = dbProviderFactory.CreateDataAdapter();
                dbAdapter.SelectCommand = dbCmd;
                DataSet returnDataSet = new DataSet();
                dbAdapter.Fill(returnDataSet);
                ClearCommandParameters(dbCmd);
                return returnDataSet;
            }
    
            public DataTable ExecuteDataTable(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                DataTable returnTable = new DataTable();
                DataSet resultDataSet = ExecuteDataSet(sqlCmdText, cmdType, paramObjs);
                if (resultDataSet != null && resultDataSet.Tables.Count > 0)
                {
                    returnTable = resultDataSet.Tables[0];
                }
                return returnTable;
            }
    
            public int ExecuteCommand(string sqlCmdText, CommandType cmdType = CommandType.Text, params object[] paramObjs)
            {
                var dbCmd = BuildDbCommand(sqlCmdText, cmdType, paramObjs);
                int execResult = dbCmd.ExecuteNonQuery();
                ClearCommandParameters(dbCmd);
                return execResult;
            }
    
            public int BatchExecuteCommand(string sqlCmdText, DbParameter[] sqlParams, DataTable srcTable, int batchSize = 0, bool needAllReChange = true)
            {
                var dbCmd = BuildDbCommand(sqlCmdText, CommandType.Text, sqlParams);
                dbCmd.UpdatedRowSource = System.Data.UpdateRowSource.None;
                var dbAdapter = dbProviderFactory.CreateDataAdapter();
                dbAdapter.AcceptChangesDuringUpdate = false;
                sqlCmdText = sqlCmdText.Trim();
                string bathExecType = System.Text.RegularExpressions.Regex.Match(sqlCmdText, @"^w+").Value.ToUpper();
                if (needAllReChange)
                {
                    srcTable.AcceptChanges();
                }
    
                switch (bathExecType)
                {
                    case "INSERT":
                        {
                            dbAdapter.InsertCommand = dbCmd;
                            if (needAllReChange)
                            {
                                foreach (DataRow row in srcTable.Rows) row.SetAdded();
                            }
                            break;
                        }
                    case "UPDATE":
                        {
                            dbAdapter.UpdateCommand = dbCmd;
                            if (needAllReChange)
                            {
                                foreach (DataRow row in srcTable.Rows) row.SetModified();
                            }
                            break;
                        }
                    case "DELETE":
                        {
                            dbAdapter.DeleteCommand = dbCmd;
                            if (needAllReChange)
                            {
                                for (int r = srcTable.Rows.Count - 1; r >= 0; r--) srcTable.Rows[r].Delete();
                            }
                            break;
                        }
                    default:
                        {
                            throw new ArgumentException("无效的SQL命令!", "sqlCmdText");
                        }
                }
    
                dbAdapter.UpdateBatchSize = batchSize;
                int execResult = dbAdapter.Update(srcTable); ;
                ClearCommandParameters(dbCmd);
                return execResult;
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
    
            #endregion
    
    
            private void Dispose(bool disposing)
            {
                if (!disposed)
                {
                    try
                    {
                        if (disposing)
                        {
                            //释放托管资源
                        }
    
                        if (dbTransaction != null)
                        {
                            if (!committed)
                            {
                                dbTransaction.Rollback();
                            }
                            dbTransaction.Dispose();
                        }
    
                        if (dbConnection != null)
                        {
                            if (dbConnection.State != ConnectionState.Closed)
                            {
                                dbConnection.Close();
                            }
                            dbConnection.Dispose();
                        }
                    }
                    catch
                    { }
    
                    disposed = true;
                }
            }
    
            ~DataAccess()
            {
                Dispose(false);
            }
    
    
    
            public ParameterHelperClass ParameterHelper
            {
                get
                {
                    return paramHelper;
                }
            }
    
    
            public class ParameterHelperClass
            {
                private List<DbParameter> parameterList = null;
                private DataAccess parent = null;
    
                public ParameterHelperClass(DataAccess da)
                {
                    parent = da;
                    parameterList = new List<DbParameter>();
                }
    
                public ParameterHelperClass AddParameter(string name, object value)
                {
                    parameterList.Add(parent.BuildDbParameter(name, value));
                    return this;
                }
    
                public ParameterHelperClass AddParameter(string name, object value, DbType dbType, int size = -1, ParameterDirection direction = ParameterDirection.Input)
                {
                    parameterList.Add(parent.BuildDbParameter(name, value, dbType, size, direction));
                    return this;
                }
    
                public ParameterHelperClass AddParameter(string name, DbType dbType, string srcColumn, int size = -1, bool srcColumnNullMapping = true, ParameterDirection direction = ParameterDirection.Input)
                {
                    parameterList.Add(parent.BuildDbParameter(name, dbType, srcColumn, size, srcColumnNullMapping, direction));
                    return this;
                }
    
                public ParameterHelperClass AddParametersWithValue(params object[] paramValues)
                {
                    for (int i = 0; i < paramValues.Length; i++)
                    {
                        parameterList.Add(parent.BuildDbParameter("@p" + i.ToString(), paramValues[i]));
                    }
                    return this;
                }
    
                public DbParameter[] ToParameterArray()
                {
                    var paramList = parameterList;
                    parameterList = new List<DbParameter>();
                    return paramList.ToArray();
                }
    
            }
    
    
        }

      

    多种灵活用法,使用示例代码如下:

    用法一:采用内联式创建参数数组对象,然后执行SQL命令

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name="test", Version="1.0", InstalledLocation=AppDomain.CurrentDomain.BaseDirectory }; 
    
                    var parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**")
                              .AddParameter("@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation))
                              .AddParameter("@SendTime", DateTime.Now)
                              .AddParameter("@KndType", "监控异常通知")
                              .ToParameterArray();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                }
    

    用法二:在用法一基础上使用事务来进行提交

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name = "test", Version = "1.0", InstalledLocation = AppDomain.CurrentDomain.BaseDirectory }; 
    
                    var parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**")
                              .AddParameter("@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation))
                              .AddParameter("@SendTime", DateTime.Now)
                              .AddParameter("@KndType", "监控异常通知")
                              .ToParameterArray();
    
                    da.UseTransaction();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.Commit();
                }
    

    用法三:在用法二基础上使用事务一次性执行多个SQL命令

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name = "test", Version = "1.0", InstalledLocation = AppDomain.CurrentDomain.BaseDirectory }; 
    
                    var parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**")
                              .AddParameter("@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation))
                              .AddParameter("@SendTime", DateTime.Now)
                              .AddParameter("@KndType", "监控异常通知")
                              .ToParameterArray();
    
                    da.UseTransaction();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.Commit();
                }
    

    用法四:在用法一基础上使用多个事务来执行多个SQL并进行多次提交

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name = "test", Version = "1.0", InstalledLocation = AppDomain.CurrentDomain.BaseDirectory };
    
                    var parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**")
                              .AddParameter("@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation))
                              .AddParameter("@SendTime", DateTime.Now)
                              .AddParameter("@KndType", "监控异常通知")
                              .ToParameterArray();
    
                    da.UseTransaction();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.Commit();
    
                    da.UseTransaction();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.Commit();
                }
    

    用法五:事务提交+SQL命令查询

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name = "test", Version = "1.0", InstalledLocation = AppDomain.CurrentDomain.BaseDirectory }; 
    
                    var parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**")
                              .AddParameter("@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation))
                              .AddParameter("@SendTime", DateTime.Now)
                              .AddParameter("@KndType", "监控异常通知")
                              .ToParameterArray();
    
                    da.UseTransaction();
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)", paramObjs: parameters);
    
                    da.Commit();
    
                    parameters = da.ParameterHelper.AddParameter("@Mbno", "188231670**").ToParameterArray();
                    var table = da.ExecuteDataTable("select Mbno,Msg,SendTime,KndType from OutBox where Mbno=@Mbno", paramObjs: parameters);
                    System.Windows.Forms.MessageBox.Show(table.Rows.Count.ToString());
                }
    

    用法六:不采用内联方式创建参数,而是执行SQL命令时直接传入各类型的参数

                using (DataAccess da = new DataAccess())
                {
                    var programInfo = new ProgramInfo() { Name = "test", Version = "1.0", InstalledLocation = AppDomain.CurrentDomain.BaseDirectory };
    
    
                    da.ExecuteCommand("insert into OutBox(Mbno,Msg,SendTime,KndType) values(@Mbno,@Msg,@SendTime,@KndType)",
                                        System.Data.CommandType.Text,
                                     new Dictionary<string, object> { 
                                        {"@Mbno", "188231670**"},
                                        {"@Msg", string.Format("程序名:{0},版本:{1},安装路径:{2},已停止运行了,请尽快处理!",
                                            programInfo.Name, programInfo.Version, programInfo.InstalledLocation)},
                                        {"@SendTime", DateTime.Now},
                                        {"@KndType", "监控异常通知"}
                                     });
    
    
                    var table = da.ExecuteDataTable("select Mbno,Msg,SendTime,KndType from OutBox where Mbno=@p0",
                                                    System.Data.CommandType.Text,
                                                    "188231670**"//若采用直接是输入值数组,那么SQL命令中的参数占位符必需定义成:@p0,@p1...
                                                );
                    System.Windows.Forms.MessageBox.Show(table.Rows.Count.ToString());
                }
    

    用法七:除了上面使用DataAccess.ParameterHelper属性的AddParameter(string name, object value)方法来创建参数,还可以使用AddParameter(string name, object value, DbType dbType, ParameterDirection direction = ParameterDirection.Input)来创建指定输入输出及类型的参数,还有AddParametersWithValue(params object[] paramValues)来根据值数组创建参数

    若需要更换数据库类型,只需要在配置文件的connectionStrings节点加入相关的连接子节点,注意providerName特性,providerName常用的如下:

    Aceess数据库:providerName="System.Data.OleDb"

    Oracle 数据库:providerName="System.Data.OracleClient"或者providerName="Oracle.DataAccess.Client"

    SQLite数据库:providerName="System.Data.SQLite"

    SQL SERVER数据库:providerName="System.Data.SqlClient"

    MYSQL数据库:providerName="MySql.Data.MySqlClient"

    ODBC连接数据库:providerName="System.Data.Odbc"

    【补充说明】

    由于目前大部份都是需要返回Model对象,故我借鉴网上的资源整合了一个基于DataTable、DataRow 通过Lambda表达式树快速转换成实体的类,代码如下:

        /// <summary>
        /// 实体转换工具类(将DataRow,DataTable,DataReader以高效方式转换为指定实体对象或实体对象列表)
        /// </summary>
        public static class EntityConverter
        {
            private static Action<T, object> GetSetter<T>(PropertyInfo property)
            {
                Type type = typeof(T);
                string key = type.AssemblyQualifiedName + "_set_" + property.Name;
    
                var result = MemoryCacheUtil.GetOrAddCacheItem<Action<T, object>>(key, () =>
                 {
                     //创建 对实体 属性赋值的expression
                     ParameterExpression parameter = Expression.Parameter(type, "t");
                     ParameterExpression value = Expression.Parameter(typeof(object), "propertyValue");
                     MethodInfo setter = type.GetMethod("set_" + property.Name);
                     MethodCallExpression call = Expression.Call(parameter, setter, Expression.Convert(value, property.PropertyType, GetConvertMethodInfo(property.PropertyType)));
                     var lambda = Expression.Lambda<Action<T, object>>(call, parameter, value);
                     var setterAction = lambda.Compile();
                     return setterAction;
                 }, null, DateTime.UtcNow.AddDays(1));
    
                return result;
            }
    
            private static MethodInfo GetConvertMethodInfo(Type propertyType)
            {
                if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(propertyType);
                    propertyType = nullableConverter.UnderlyingType;
                }
                var convertMethod = typeof(Convert).GetMethod("ToString", new[] { typeof(object) });
                if (new[] { typeof(int), typeof(long), typeof(decimal), typeof(float), typeof(double) }.Contains(propertyType))
                {
                    convertMethod = typeof(Convert).GetMethod("To" + propertyType.Name, new[] { typeof(object) });
                }
                else if (typeof(bool).Equals(propertyType))
                {
                    convertMethod = typeof(Convert).GetMethod("ToBoolean", new[] { typeof(object) });
                }
                else if (typeof(DateTime).Equals(propertyType))
                {
                    convertMethod = typeof(Convert).GetMethod("ToDateTime", new[] { typeof(object) });
                }
    
                return convertMethod;
            }
    
            public static T To<T>(DataRow row, PropertyInfo[] props = null) where T : new()
            {
                T model = new T();
                if (props == null)
                {
                    props = typeof(T).GetProperties();
                }
    
                foreach (PropertyInfo prop in props)
                {
                    if (row.Table.Columns.IndexOf(prop.Name) >= 0)
                    {
                        var setterAction = GetSetter<T>(prop);
                        if (prop != null && row[prop.Name] != DBNull.Value)
                            setterAction(model, row[prop.Name]);
                    }
                }
    
                return model;
            }
    
    
            public static T To<T>(DataRow row, Func<string, object, object> beforePropFunc, PropertyInfo[] props = null) where T : new()
            {
                T model = new T();
                if (props == null)
                {
                    props = typeof(T).GetProperties();
                }
    
                foreach (PropertyInfo prop in props)
                {
                    if (row.Table.Columns.IndexOf(prop.Name) >= 0)
                    {
                        var setterAction = GetSetter<T>(prop);
                        if (prop != null && row[prop.Name] != DBNull.Value)
                        {
                            object propValue = beforePropFunc(prop.Name, row[prop.Name]);
                            setterAction(model, propValue);
                        }
                    }
                }
    
                return model;
            }
    
            public static List<T> ToList<T>(this DataTable dt) where T : new()
            {
                List<T> list = new List<T>();
                if (dt == null || dt.Rows.Count == 0)
                {
                    return list;
                }
    
                var props = typeof(T).GetProperties();
                foreach (DataRow dr in dt.Rows)
                {
                    var t = To<T>(dr, props);
                    list.Add(t);
                }
    
                return list;
            }
    
    
            public static List<T> ToList<T>(this DataTable dt, Func<T, PropertyInfo[], T> afterFunc) where T : new()
            {
                List<T> list = new List<T>();
                if (dt == null || dt.Rows.Count == 0)
                {
                    return list;
                }
                var props = typeof(T).GetProperties();
                foreach (DataRow dr in dt.Rows)
                {
                    var t = To<T>(dr, props);
                    t = afterFunc(t,props);
                    list.Add(t);
                }
    
                return list;
            }
    
            public static List<T> ToList<T>(IDataReader dr) where T : new()
            {
                List<T> list = new List<T>();
                var props = typeof(T).GetProperties();
                while (dr.Read())
                {
                    T t = new T();
                    foreach (PropertyInfo prop in props)
                    {
                        if (prop != null && dr[prop.Name] != DBNull.Value)
                            GetSetter<T>(prop)(t, dr[prop.Name]);
                    }
                    list.Add(t);
                }
                return list;
            }
    
            public static List<T> ToList<T>(IEnumerable<DataRow> rows) where T : new()
            {
                List<T> list = new List<T>();
                if (rows == null || rows.Count() == 0)
                {
                    return list;
                }
    
                var props = typeof(T).GetProperties();
                foreach (DataRow dr in rows)
                {
                    var t = To<T>(dr, props);
                    list.Add(t);
                }
    
                return list;
            }
        }
    

    用法很简单,直接在查询结果后面使用扩展方法,示例如下:

    var table = da.ExecuteDataTable("select Mbno,Msg,SendTime,KndType from OutBox where Mbno=@p0",
                                                    System.Data.CommandType.Text,
                                                    "188231670**"//若采用直接是输入值数组,那么SQL命令中的参数占位符必需定义成:@p0,@p1...
                                                );
    //第一种将上面的table再次使用扩展方法进行转换
    List<ResultModel> resultList= table.ToList<ResultModel>();
    
    //第二种在执行后直接使用扩展方法进行转换(其实本质都是一样的,只是这里只需一步)
    var resultList= da.ExecuteDataTable("select Mbno,Msg,SendTime,KndType from OutBox where Mbno=@p0",
                                                    System.Data.CommandType.Text,
                                                    "188231670**"//若采用直接是输入值数组,那么SQL命令中的参数占位符必需定义成:@p0,@p1...
                                                ).ToList<ResultModel>();
    

      

  • 相关阅读:
    Flask web开发之路二
    Flask web开发之路一
    英文文本挖掘预处理总结
    TF-IDF概念
    MongoDB数据库去重
    Python把两个列表合成一个字典
    网络通信协议七之ARP工作过程及工作原理解析
    Python基础爬虫
    Red and Black 模板题 /// BFS oj22063
    Alice拜年 模板题 /// 最短路Dijk oj1344
  • 原文地址:https://www.cnblogs.com/zuowj/p/5557193.html
Copyright © 2011-2022 走看看