草庐IT

国产化之 .NET Core 操作达梦数据库DM8的两种方式

波斯马 2023-03-28 原文

背景

某个项目需要实现基础软件全部国产化,其中操作系统指定银河麒麟,数据库使用达梦V8,CPU平台的范围包括x64、龙芯、飞腾、鲲鹏等。考虑到这些基础产品对.NET的支持,最终选择了.NET Core 3.1。

环境

  • CPU平台:x86-64 / Arm64
  • 操作系统:银河麒麟 v4
  • 数据库:DM8
  • .NET:.NET Core 3.1

SDK

达梦自己提供了.NET操作其数据库的SDK,可以通过NuGet安装,也可以通过安装达梦数据库获取。因为NuGet上的版本不知道是谁提供的,所以这里以安装数据库获取相关SDK为例。

在官网下载DM8的数据库安装文件:https://www.dameng.com/list_103.html

下载前需要先登录,随便注册一个帐号就好了。

这里需要选择CPU和操作系统,按照你的开发环境选择即可,下载后按照提示安装。

这里以Windows10为例,安装后SDK文件的位置在:C:\dmdbms\drivers\dotNet

这里边有EF的SDK,也有NHibernate的SDK,不过这篇文章只使用最基础的基于ADO.NET的SDK。

这些SDK在文件夹DmProvider下边,这里还提供了一个Nuget包,可以放到自己的Nuget仓库中,方便内部安装。

可以看到,这个SDK可以支持.NET Core2.0以上的所有.NET版本。

操作数据库

这里提供两种方式:传统的DbHelperSQL方式 和 Dapper 方式。

DbHelperSQL方式

这种方式早年用的比较多,现在还有很多项目在使用,通过定义一组工具方法包装对数据库的各种增删改查操作。下面给出代码:

    public class DmDbClient
    {
        private string connectionString = string.Empty;

        /// <summary>
        /// 初始化DMClient的一个新实例
        /// </summary>
        /// <param name="str"></param>
        public DmDbClient(string str)
        {
            connectionString = str;
        }

        #region 通用快捷方法
        /// <summary>
        /// 执行一条SQL语句,确定记录是否存在
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <returns></returns>
        public bool Exists(string sql)
        {
            object obj = GetSingle(sql);

            int cmdresult;
            if (Equals(obj, null) || Equals(obj, DBNull.Value))
            {
                cmdresult = 0;
            }
            else
            {
                cmdresult = int.Parse(obj.ToString());
            }

            return cmdresult > 0;
        }

        /// <summary>
        /// 执行一条SQL语句,确定记录是否存在
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <returns></returns>
        public async Task<bool> ExistsAsync(string sql)
        {
            object obj = await GetSingleAsync(sql);

            int cmdresult;
            if (Equals(obj, null) || Equals(obj, DBNull.Value))
            {
                cmdresult = 0;
            }
            else
            {
                cmdresult = int.Parse(obj.ToString());
            }

            return cmdresult > 0;
        }

        /// <summary>
        /// 执行一条SQL语句,确定记录是否存在
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns></returns>
        public bool Exists(string sql, params DmParameter[] paras)
        {
            object obj = GetSingle(sql, paras);

            int cmdresult;
            if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
            {
                cmdresult = 0;
            }
            else
            {
                cmdresult = int.Parse(obj.ToString());
            }

            return cmdresult > 0;
        }

        /// <summary>
        /// 执行一条SQL语句,确定记录是否存在
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns></returns>
        public async Task<bool> ExistsAsync(string sql, params DmParameter[] paras)
        {
            object obj = await GetSingleAsync(sql, paras);

            int cmdresult;
            if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
            {
                cmdresult = 0;
            }
            else
            {
                cmdresult = int.Parse(obj.ToString());
            }

            return cmdresult > 0;
        }

        /// <summary>
        /// 获取记录条数
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="sqlCondition">查询条件</param>
        /// <returns></returns>
        public int GetCount(string tableName, string sqlCondition)
        {
            string sql = "select count(1) from `" + tableName + "`";

            if (!string.IsNullOrWhiteSpace(sqlCondition))
            {
                sql += " where " + sqlCondition;
            }

            object result = GetSingle(sql);

            if (result != null)
            {
                return Convert.ToInt32(result);
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取记录条数
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="sqlCondition">查询条件</param>
        /// <returns></returns>
        public async Task<int> GetCountAsync(string tableName, string sqlCondition)
        {
            string sql = "select count(1) from `" + tableName + "`";

            if (!string.IsNullOrWhiteSpace(sqlCondition))
            {
                sql += " where " + sqlCondition;
            }

            object result = await GetSingleAsync(sql);

            if (result != null)
            {
                return Convert.ToInt32(result);
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取记录条数
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="sqlCondition">查询条件</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns></returns>
        public int GetCount(string tableName, string sqlCondition, DmParameter[] paras)
        {
            string sql = "select count(1) from `" + tableName + "`";

            if (!string.IsNullOrWhiteSpace(sqlCondition))
            {
                sql += " where " + sqlCondition;
            }

            object result = GetSingle(sql, paras);

            if (result != null)
            {
                return Convert.ToInt32(result);
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取记录条数
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="sqlCondition">查询条件</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns></returns>
        public async Task<int> GetCountAsync(string tableName, string sqlCondition, DmParameter[] paras)
        {
            string sql = "select count(1) from `" + tableName + "`";

            if (!string.IsNullOrWhiteSpace(sqlCondition))
            {
                sql += " where " + sqlCondition;
            }

            object result = await GetSingleAsync(sql, paras);

            if (result != null)
            {
                return Convert.ToInt32(result);
            }
            else
            {
                return 0;
            }
        }

        #endregion 通用快捷方法

        #region 执行简单SQL语句

        /// <summary>
        /// 执行SQL语句,返回影响的记录数
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>影响的记录数</returns>
        public int ExecuteSql(string sql)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    connection.Open();
                    int rows = cmd.ExecuteNonQuery();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行SQL语句,返回影响的记录数
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>影响的记录数</returns>
        public async Task<int> ExecuteSqlAsync(string sql)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    await connection.OpenAsync();
                    int rows = await cmd.ExecuteNonQueryAsync();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行SQL语句,返回影响的记录数(可自定义超时时间)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="timeout">执行超时时间</param>
        /// <returns>影响的记录数</returns>
        public int ExecuteSqlByTime(string sql, int timeout)
        {
            using (DmConnection connection = new DmConnection(this.connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    connection.Open();
                    cmd.CommandTimeout = timeout;
                    int rows = cmd.ExecuteNonQuery();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行SQL语句,返回影响的记录数(可自定义超时时间)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="timeout">执行超时时间</param>
        /// <returns>影响的记录数</returns>
        public async Task<int> ExecuteSqlByTimeAsync(string sql, int timeout)
        {
            using (DmConnection connection = new DmConnection(this.connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    await connection.OpenAsync();
                    cmd.CommandTimeout = timeout;
                    int rows = await cmd.ExecuteNonQueryAsync();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="sqlList">多条SQL语句</param>
        public void ExecuteSqlTrans(ArrayList sqlList)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                conn.Open();
                using (DbTransaction trans = conn.BeginTransaction())
                {
                    using (DmCommand cmd = new DmCommand())
                    {
                        cmd.Connection = conn;
                        cmd.Transaction = trans;

                        try
                        {
                            for (int n = 0; n < sqlList.Count; n++)
                            {
                                string sql = sqlList[n].ToString();

                                if (sql.Trim().Length > 1)
                                {
                                    cmd.CommandText = sql;
                                    cmd.ExecuteNonQuery();
                                }
                            }

                            trans.Commit();
                        }
                        catch (DmException ex)
                        {
                            trans.Rollback();
                            throw ex;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="sqlList">多条SQL语句</param>
        public async Task ExecuteSqlTransAsync(ArrayList sqlList)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                await conn.OpenAsync();
                using (DbTransaction trans = await conn.BeginTransactionAsync())
                {
                    using (DmCommand cmd = new DmCommand())
                    {
                        cmd.Connection = conn;
                        cmd.Transaction = trans;

                        try
                        {
                            for (int n = 0; n < sqlList.Count; n++)
                            {
                                string sql = sqlList[n].ToString();

                                if (sql.Trim().Length > 1)
                                {
                                    cmd.CommandText = sql;
                                    await cmd.ExecuteNonQueryAsync();
                                }
                            }

                            trans.Commit();
                        }
                        catch (DmException ex)
                        {
                            trans.Rollback();
                            throw ex;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行一条SQL查询语句,返回查询结果。
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <returns>查询结果</returns>
        public object GetSingle(string sql)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    connection.Open();

                    object obj = cmd.ExecuteScalar();

                    if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
                    {
                        return null;
                    }
                    else
                    {
                        return obj;
                    }
                }
            }
        }

        /// <summary>
        /// 执行一条SQL查询语句,返回查询结果。
        /// </summary>
        /// <param name="sql">SQL查询语句</param>
        /// <returns>查询结果</returns>
        public async Task<object> GetSingleAsync(string sql)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand(sql, connection))
                {
                    await connection.OpenAsync();

                    object obj = await cmd.ExecuteScalarAsync();

                    if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
                    {
                        return null;
                    }
                    else
                    {
                        return obj;
                    }
                }
            }
        }

        /// <summary>
        /// 执行查询语句,返回DbDataReader(切记要手工关闭DbDataReader)
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>DmDataReader</returns>
        public DbDataReader ExecuteReader(string sql)
        {
            DmConnection connection = new DmConnection(connectionString);
            DmCommand cmd = new DmCommand(sql, connection);

            connection.Open();
            return cmd.ExecuteReader();
        }

        /// <summary>
        /// 执行查询语句,返回DbDataReader(切记要手工关闭DbDataReader)
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>DmDataReader</returns>
        public async Task<DbDataReader> ExecuteReaderAsync(string sql)
        {
            DmConnection connection = new DmConnection(connectionString);
            DmCommand cmd = new DmCommand(sql, connection);

            await connection.OpenAsync();
            return await cmd.ExecuteReaderAsync();
        }

        /// <summary>
        /// 执行查询语句,返回DataSet
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>DataSet</returns>
        public DataSet Query(string sql)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmDataAdapter command = new DmDataAdapter(sql, connection))
                {
                    DataSet ds = new DataSet();

                    connection.Open();
                    command.Fill(ds, "ds");

                    return ds;
                }
            }
        }

        /// <summary>
        /// 执行查询语句,返回DataSet(可自定义超时时间)
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public DataSet Query(string sql, int timeout)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmDataAdapter command = new DmDataAdapter(sql, connection))
                {
                    DataSet ds = new DataSet();

                    connection.Open();
                    command.SelectCommand.CommandTimeout = timeout;
                    command.Fill(ds, "ds");

                    return ds;
                }
            }
        }
        #endregion 执行简单SQL语句

        #region 执行带参数的SQL语句

        /// <summary>
        /// 执行SQL语句,返回影响的记录数
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns>影响的记录数</returns>
        public int ExecuteSql(string sql, params DmParameter[] paras)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    PrepareCommand(cmd, connection, null, sql, paras);
                    int rows = cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行SQL语句,返回影响的记录数
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="paras">SQL参数数组</param>
        /// <returns>影响的记录数</returns>
        public async Task<int> ExecuteSqlAsync(string sql, params DmParameter[] paras)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    await PrepareCommandAsync(cmd, connection, null, sql, paras);
                    int rows = await cmd.ExecuteNonQueryAsync();
                    cmd.Parameters.Clear();
                    return rows;
                }
            }
        }

        /// <summary>
        /// 执行添加SQL语句,返回记录的ID(自动产生的自增主键)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>记录的ID</returns>
        public int ExecuteAdd(string sql, params DmParameter[] parms)
        {
            sql = sql + ";Select @@IDENTITY";

            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    PrepareCommand(cmd, connection, null, sql, parms);
                    int recordID = Int32.Parse(cmd.ExecuteScalar().ToString());
                    cmd.Parameters.Clear();

                    return recordID;
                }
            }
        }

        /// <summary>
        /// 执行添加SQL语句,返回记录的ID(自动产生的自增主键)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>记录的ID</returns>
        public async Task<int> ExecuteAddAsync(string sql, params DmParameter[] parms)
        {
            sql = sql + ";select @@identity as newautoid";

            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    await PrepareCommandAsync(cmd, connection, null, sql, parms);

                    int recordID;
                    try
                    {
                        recordID = int.Parse((await cmd.ExecuteScalarAsync()).ToString());
                    }
                    catch
                    {
                        recordID = -1;
                    }

                    cmd.Parameters.Clear();

                    return recordID;
                }
            }
        }

        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="sqlList">SQL语句的哈希表(key为sql语句,value是该语句的DmParameter[])</param>
        public void ExecuteSqlTrans(Hashtable sqlList)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                conn.Open();
                using (DbTransaction trans = conn.BeginTransaction())
                {
                    using (DmCommand cmd = new DmCommand())
                    {
                        try
                        {
                            foreach (DictionaryEntry entry in sqlList)
                            {
                                var sql = entry.Key.ToString();
                                var paras = (DmParameter[])entry.Value;

                                PrepareCommand(cmd, conn, trans, sql, paras);

                                int val = cmd.ExecuteNonQuery();

                                cmd.Parameters.Clear();
                            }

                            trans.Commit();
                        }
                        catch (DmException ex)
                        {
                            trans.Rollback();
                            throw ex;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="sqlList">SQL语句的哈希表(key为sql语句,value是该语句的DmParameter[])</param>
        public async Task ExecuteSqlTransAsync(Hashtable sqlList)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                await conn.OpenAsync();
                using (DbTransaction trans = conn.BeginTransaction())
                {
                    using (DmCommand cmd = new DmCommand())
                    {
                        try
                        {
                            foreach (DictionaryEntry entry in sqlList)
                            {
                                var sql = entry.Key.ToString();
                                var paras = (DmParameter[])entry.Value;

                                await PrepareCommandAsync(cmd, conn, trans, sql, paras);

                                int val = await cmd.ExecuteNonQueryAsync();

                                cmd.Parameters.Clear();
                            }

                            trans.Commit();
                        }
                        catch (DmException ex)
                        {
                            trans.Rollback();
                            throw ex;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行一条计算查询结果语句,返回查询结果。
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>查询结果</returns>
        public object GetSingle(string sql, params DmParameter[] parms)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    PrepareCommand(cmd, conn, null, sql, parms);

                    object obj = cmd.ExecuteScalar();
                    cmd.Parameters.Clear();

                    if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
                    {
                        return null;
                    }
                    else
                    {
                        return obj;
                    }
                }
            }
        }

        /// <summary>
        /// 执行一条计算查询结果语句,返回查询结果。
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>查询结果</returns>
        public async Task<object> GetSingleAsync(string sql, params DmParameter[] parms)
        {
            using (DmConnection conn = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    await PrepareCommandAsync(cmd, conn, null, sql, parms);

                    object obj = await cmd.ExecuteScalarAsync();
                    cmd.Parameters.Clear();

                    if ((object.Equals(obj, null)) || (object.Equals(obj, DBNull.Value)))
                    {
                        return null;
                    }
                    else
                    {
                        return obj;
                    }
                }
            }
        }

        /// <summary>
        /// 执行查询语句,返回DmDataReader (切记要手工关闭DmDataReader)
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>DmDataReader</returns>
        public DbDataReader ExecuteReader(string sql, params DmParameter[] parms)
        {
            DmConnection connection = new DmConnection(connectionString);
            DmCommand cmd = new DmCommand();

            PrepareCommand(cmd, connection, null, sql, parms);

            DbDataReader myReader = cmd.ExecuteReader();
            cmd.Parameters.Clear();

            return myReader;
        }

        /// <summary>
        /// 执行查询语句,返回DmDataReader (切记要手工关闭DmDataReader)
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="parms">SQL参数</param>
        /// <returns>DmDataReader</returns>
        public async Task<DbDataReader> ExecuteReaderAsync(string sql, params DmParameter[] parms)
        {
            DmConnection connection = new DmConnection(connectionString);
            DmCommand cmd = new DmCommand();

            await PrepareCommandAsync(cmd, connection, null, sql, parms);

            var myReader = await cmd.ExecuteReaderAsync();
            cmd.Parameters.Clear();
            return myReader;
        }

        /// <summary>
        /// 执行查询语句,返回DataSet
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="paras">参数数组</param>
        /// <returns>DataSet</returns>
        public DataSet Query(string sql, params DmParameter[] paras)
        {
            using (DmConnection connection = new DmConnection(connectionString))
            {
                using (DmCommand cmd = new DmCommand())
                {
                    PrepareCommand(cmd, connection, null, sql, paras);
                    DataSet ds = new DataSet();

                    using (DmDataAdapter da = new DmDataAdapter(cmd))
                    {
                        da.Fill(ds, "ds");
                        cmd.Parameters.Clear();

                        return ds;
                    }
                }
            }
        }

        /// <summary>
        /// 准备SQL查询命令
        /// </summary>
        /// <param name="cmd">SQL命令对象</param>
        /// <param name="conn">SQL连接对象</param>
        /// <param name="trans">SQL事务对象</param>
        /// <param name="cmdText">SQL语句</param>
        /// <param name="paras">SQL参数数组</param>
        private void PrepareCommand(DmCommand cmd, DmConnection conn, DbTransaction trans, string cmdText, DmParameter[] paras)
        {
            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }

            cmd.Connection = conn;
            cmd.CommandText = cmdText;

            if (trans != null)
            {
                cmd.Transaction = trans;
            }

            cmd.CommandType = CommandType.Text;
            if (paras != null)
            {
                foreach (DmParameter parameter in paras)
                {
                    if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
                        (parameter.Value == null))
                    {
                        parameter.Value = DBNull.Value;
                    }
                    cmd.Parameters.Add(parameter);
                }
            }
        }

        /// <summary>
        /// 准备SQL查询命令
        /// </summary>
        /// <param name="cmd">SQL命令对象</param>
        /// <param name="conn">SQL连接对象</param>
        /// <param name="trans">SQL事务对象</param>
        /// <param name="cmdText">SQL语句</param>
        /// <param name="paras">SQL参数数组</param>
        private async Task PrepareCommandAsync(DmCommand cmd, DmConnection conn, DbTransaction trans, string cmdText, DmParameter[] paras)
        {
            if (conn.State != ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            cmd.Connection = conn;
            cmd.CommandText = cmdText;

            if (trans != null)
            {
                cmd.Transaction = trans;
            }

            cmd.CommandType = CommandType.Text;
            if (paras != null)
            {
                foreach (DmParameter parameter in paras)
                {
                    if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
                        (parameter.Value == null))
                    {
                        parameter.Value = DBNull.Value;
                    }
                    cmd.Parameters.Add(parameter);
                }
            }
        }

        #endregion 执行带参数的SQL语句
    }

使用方法也很简单,传入SQL语句和参数即可。这里给出几个增删改查的例子:

    public class PersonAdoNetDAL : IPersonDAL
    {
        static readonly DmDbClient _client = new DmDbClient("Server=127.0.0.1; UserId=TESTDB; PWD=1234567");

        public int Add(PersonModel model)
        {
            string sql = "insert into Person(Name,City) Values(:Name,:City)";
            DmParameter[] paras = new DmParameter[] {
                new DmParameter(":Name",model.Name),
                new DmParameter(":City",model.City)
            };

            return _client.ExecuteAdd(sql, paras);
        }

        public bool Update(PersonModel model)
        {
            string sql = "update Person set City=:City where Id=:Id";
            DmParameter[] paras = new DmParameter[] {
                new DmParameter(":Id",model.Id),
                new DmParameter(":City",model.City)
            };

            return _client.ExecuteSql(sql, paras) > 0 ? true : false;
        }

        public bool Delete(int id)
        {
            string sql = "delete from Person where Id=:Id";
            DmParameter[] paras = new DmParameter[] {
                new DmParameter(":Id",id),
            };

            return _client.ExecuteSql(sql, paras) > 0 ? true : false;
        }

        public PersonModel Get(int id)
        {
            string sql = "select Id,Name,City from Person where Id=:Id";
            DmParameter[] paras = new DmParameter[] {
                new DmParameter(":Id",id),
            };

            PersonModel model = null;
            using (var reader = (DmDataReader)_client.ExecuteReader(sql, paras))
            {
                while (reader.Read())
                {
                    model = new PersonModel();
                    model.Id = reader.GetInt32(0);
                    model.Name = reader.GetString(1);
                    model.City = reader.GetString(2);
                }
            }

            return model;
        }

        public List<PersonModel> GetList()
        {
            var list = new List<PersonModel>();
            using (var reader = (DmDataReader)_client.ExecuteReader("select Id,Name,City from Person"))
            {
                while (reader.Read())
                {
                    var model = new PersonModel();
                    model.Id = reader.GetInt32(0);
                    model.Name = reader.GetString(1);
                    model.City = reader.GetString(2);
                    list.Add(model);
                }
            }

            return list;
        }

    }

需要注意达梦数据库的参数是用冒号作为前缀的。另外数据表和字段的名字建议全部使用大写字母,单词之间使用下划线分隔,也就是蛇形命名法。此时SQL语句就不用关心大小写了,怎么写都行。

Dapper方式

Dapper是一个轻量级的ORM框架,现在使用的也很广泛,可以简化代码编写。因为Dapper扩展的IDbConnection,这是ADO.NET中的东西,我们使用的DmProvider也是实现了ADO.NET相关接口,所以Dapper可以通过DmProvider操作达梦数据库。

首先定义一个获取数据库连接对象的工厂类:

    public class DmConnectionFactory
    {
        static string sqlConnString = "Server=127.0.0.1; UserId=TESTDB; PWD=123456";
        public static IDbConnection GetConn()
        {
            return new DmConnection(sqlConnString);
        }
    }

然后就可以使用它执行SQL语句了:

   public class PersonDapperDAL : IPersonDAL
    {
        public PersonDapperDAL()
        {
        }

        public PersonModel Get(int id)
        {
            string sql = "select Id,Name,City from Person where Id=:Id";
            return DmConnectionFactory.GetConn().QueryFirstOrDefault<PersonModel>(sql, new { Id = id });
        }

        public List<PersonModel> GetList()
        {
            string sql = "select Id,Name,City from Person";
            return DmConnectionFactory.GetConn().Query<PersonModel>(sql).ToList();
        }

        public int Add(PersonModel model)
        {
            string sql = "insert into Person(Name,City) Values(:Name,:City);Select @@IDENTITY";
            return DmConnectionFactory.GetConn().QuerySingle<int>(sql, model);
        }

        public bool Update(PersonModel model)
        {
            string sql = "update Person set City=:City where Id=:Id";
            int result = DmConnectionFactory.GetConn().Execute(sql, model);
            return result > 0;
        }

        public bool Delete(int id)
        {
            string sql = "delete from Person where Id=:Id";
            int result = DmConnectionFactory.GetConn().Execute(sql, new { Id = id });
            return result > 0;
        }
    }

Query、Execute这些方法都是Dapper定义的,可以看到能够少写很多代码。这里也不用打开连接、关闭连接,也不用写using,因为Dapper的这些方法中已经做了相关处理。


好了,以上就是本文的主要内容。如有错漏欢迎指正。

收获更多架构知识,请关注微信公众号 萤火架构。原创内容,转载请注明出处。

有关国产化之 .NET Core 操作达梦数据库DM8的两种方式的更多相关文章

  1. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  2. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  3. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  4. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  5. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

  6. ruby-on-rails - 如何让 datamapper 与 postgresql 数据库一起工作? - 2

    我已经找到了几个使用datamapper的示例,并且能够让它们正常工作。不过,所有这些示例都是针对sqlite数据库的。我正在尝试将数据映射器与postgresql一起使用。我将datamapper中的调用从sqlite3更改为postgres,并且我已经安装了dm-postgres-adapter。但它仍然不起作用。我还需要做什么? 最佳答案 与SQLite不同,PostgreSQL不将数据库存储在单个文件中。在你拥有createdyourdatabase之后,尝试这样的事情:DataMapper.setup:default,{:

  7. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  8. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  9. ruby-on-rails - rails 多态关联(遗留数据库) - 2

    我使用的是遗留数据库,所以我无法控制数据模型。他们使用了很多多态链接/连接表,就像这样createtableperson(per_ident,name,...)createtableperson_links(per_ident,obj_name,obj_r_ident)createtablereport(rep_ident,name,...)其中obj_name是表名,obj_r_ident是标识符。因此链接的报告将按如下方式插入:insertintoperson(1,...)insertintoreport(1,...)insertintoreport(2,...)insertint

  10. ruby-on-rails - 在现有数据库上进行 Rails 迁移 - 2

    我正在创建一个新的Rails3.1应用程序。我希望这个新应用程序重用现有数据库(由以前的Rails2应用程序创建)。我创建了新的应用程序定义模型,它重用了数据库中的一些现有数据。在开发和测试阶段,一切正常,因为它在干净的表数据库上运行,但是当尝试部署到生产环境时,我收到如下消息:PGError:ERROR:column"email"ofrelation"users"alreadyexists***[err::localhost]:ALTERTABLE"users"ADDCOLUMN"email"charactervarying(255)DEFAULT''NOTNULL但是我在迁移中有这

随机推荐