微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#/ASP.NET完善的DBHelper,配套Model生成器

支持Oracle、MSsqlMysqLsqlite四种数据库支持事务,支持对象关系映射;已在多个项目中实际使用。

没有语法糖,学习成本几乎为0,拿来即用。

DBHelper类完整代码

using System;
 System.Collections.Generic;
 System.ComponentModel;
 System.Configuration;
 System.Data;
 System.Data.Common;
 System.Data.Objects.DataClasses;
 System.Data.OracleClient;
 System.Data.sqlClient;
 System.Data.sqlite;
 System.Reflection;
 System.Text;
 System.Text.RegularExpressions;
 MysqL.Data.MysqLClient;
 System.Data.OleDb;
 Models;

/* ----------------------------------------------------------------------
 * 作    者:suxiang
 * 创建日期:2016年11月23日
 * 更新日期:2020年06月16日
 * 
 * 支持Oracle、MSsqlMysqLsqlite、Access数据库
 * 
 * 注意引用的MysqL.Data.dll、System.Data.sqlite.dll的版本,32位还是64位
 * 有的System.Data.sqlite.dll版本需要依赖sqlite.Interop.dll
 * 
 * 需要配套的PagerModel、IsDBFieldAttribute、IsIdAttribute类
 * 
 * 为方便使用,需要配套的Model生成器
 * ---------------------------------------------------------------------- */

namespace DBUtil
{
    /// <summary>
    /// 数据库操作类
    </summary>
    public static class DBHelper
    {
        #region 变量
        <summary>
         数据库类型
        </summary>
        private string m_DBType = ConfigurationManager.AppSettings["DBType"];
        bool m_AutoIncrement = ConfigurationManager.AppSettings[AutoIncrement"].ToLower() == true" ? true : false;
         数据库连接字符串
        string m_ConnectionString = ConfigurationManager.ConnectionStrings[DefaultConnection].ToString();
         事务
        </summary>
        [ThreadStatic]
        static DbTransaction m_Tran;
         带参数的sql插入和修改语句中,参数前面的符号
        string m_ParameterMark = GetParameterMark();

         sql过滤正则
        static Dictionary<string,Regex> m_sqlFilteRegexList = new Dictionary<();
        #endregion

        #region 静态构造函数
         静态构造函数
         DBHelper()
        {
            m_sqlFilteRegexList.Add(net localgroup ",new Regex(net[\\s]+localgroup[\\s]+,RegexOptions.IgnoreCase));
            m_sqlFilteRegexList.Add(net user net[\\s]+user[\\s]+xp_cmdshell xp_cmdshell[\\s]+exec exec[\\s]+execute execute[\\s]+truncate truncate[\\s]+drop drop[\\s]+restore restore[\\s]+create create[\\s]+alter alter[\\s]+rename rename[\\s]+insert insert[\\s]+update update[\\s]+delete delete[\\s]+select select[\\s]+noreCase));
        }
        #region 生成变量
        #region 生成 IDbCommand
         生成 IDbCommand
         DbCommand GetCommand()
        {
            DbCommand command = null;

            switch (m_DBType)
            {
                case oracle:
                    command = new OracleCommand();
                    break;
                mssql sqlCommand();
                    MysqL MysqLCommand();
                    sqlite sqliteCommand();
                    access OleDbCommand();
                    ;
            }

            return command;
        }
        static DbCommand GetCommand(string sql,DbConnection conn)
        {
            DbCommand command =  OracleCommand(sql);
                    command.Connection = conn;
                     sqlCommand(sql);
                    command.Connection = MysqLCommand(sql);
                    command.Connection = sqliteCommand(sql);
                    command.Connection = OleDbCommand(sql);
                    command.Connection = command;
        }
        #region 生成 IDbConnection
         生成 IDbConnection
         DbConnection GetConnection()
        {
            DbConnection conn = :
                    conn =  OracleConnection(m_ConnectionString);
                     sqlConnection(m_ConnectionString);
                     MysqLConnection(m_ConnectionString);
                     sqliteConnection(m_ConnectionString);
                     OleDbConnection(m_ConnectionString);
                     conn;
        }
        #region 生成 IDbDataAdapter
         生成 IDbDataAdapter
         DbDataAdapter GetDataAdapter(DbCommand cmd)
        {
            DbDataAdapter dataAdapter = :
                    dataAdapter =  OracleDataAdapter();
                    dataAdapter.SelectCommand = cmd;
                     sqlDataAdapter();
                    dataAdapter.SelectCommand = MysqLDataAdapter();
                    dataAdapter.SelectCommand = sqliteDataAdapter();
                    dataAdapter.SelectCommand = OleDbDataAdapter();
                    dataAdapter.SelectCommand = dataAdapter;
        }
        #region 生成 m_ParameterMark
         生成 m_ParameterMark
         GetParameterMark()
        {
            :
                    return :@;
            }
            ;
        }
        #region 生成 DbParameter
         生成 DbParameter
        static DbParameter GetDbParameter(string name,1)">object vallue)
        {
            DbParameter dbParameter = :
                    dbParameter =  OracleParameter(name,vallue);
                     sqlParameter(name,1)"> MysqLParameter(name,1)"> sqliteParameter(name,1)"> OleDbParameter(name,1)"> dbParameter;
        }
        #endregion
        #region 基础方法
        #region  执行简单sql语句
        #region Exists
        bool Exists( sqlString)
        {
            sqlFilter(ref sqlString);
            using (DbConnection conn = GetConnection())
            {
                using (DbCommand cmd = GetCommand(sqlString,conn))
                {
                    try
                    {
                        conn.open();
                        object obj = cmd.ExecuteScalar();
                        if ((Object.Equals(obj,1)">null)) || (Object.Equals(obj,System.dbnull.Value)))
                        {
                            return ;
                        }
                        else
                        {
                            true;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                    finally
                    {
                        cmd.dispose();
                        conn.Close();
                    }
                }
            }
        }
        #region 执行sql语句,返回影响的记录数
         执行sql语句,返回影响的记录数
        </summary>
        <param name="sqlString">sql语句</param>
        <returns>影响的记录数</returns>
        int Executesql( sqlString);
            DbConnection conn = m_Tran == null ? GetConnection() : m_Tran.Connection;
            
                {
                    if (conn.State != ConnectionState.Open) conn.open();
                    if (m_Tran != null) cmd.Transaction = m_Tran;
                    int rows = cmd.ExecuteNonQuery();
                     rows;
                }
                 (Exception ex)
                {
                    throw  Exception(ex.Message);
                }
                
                {
                    cmd.dispose();
                    if (m_Tran == ) conn.Close();
                }
            }
        }
        #region 执行一条计算查询结果语句,返回查询结果
         执行一条计算查询结果语句,返回查询结果(object)
        计算查询结果语句查询结果(object)object GetSingle(
                    {
                         ConnectionState.Open) conn.open();
                         obj;
                        }
                    }
                    
                    {
                        cmd.dispose();
                    }
                }
            }
        }
        #region 执行查询语句,返回IDataReader
         执行查询语句,返回IDataReader ( 注意:调用方法后,一定要对IDataReader进行Close )
        查询语句IDataReaderstatic DbDataReader ExecuteReader( sqlString);
            DbConnection conn = GetConnection();
            DbCommand cmd =
            {
                 ConnectionState.Open) conn.open();
                DbDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                 myReader;
            }
             (Exception ex)
            {
                 ex;
            }
        }
        #region 执行查询语句,返回DataSet
         执行查询语句,返回DataSet
        DataSetstatic DataSet Query( GetConnection())
            {
                DataSet ds =  DataSet();
                
                {
                    conn.open();
                     GetDataAdapter(cmd);
                        adapter.Fill(ds,ds);
                    }
                }
                 ex;
                }
                
                {
                    conn.Close();
                }
                 ds;
            }
        }
        #region sql过滤,防注入
         sql过滤,防注入
        <param name="sql">sql</param>
        void sqlFilter(ref  sql)
        {
            sql = sql.Trim();
            string ignore = .Empty;
            string uppersql = sql.toupper();
            foreach (string keyword in m_sqlFilteRegexList.Keys)
            {
                if (uppersql.IndexOf(keyword.toupper()) == 0)
                {
                    ignore = keyword;
                }
            }
            if (ignore == " && ignore == keyword) continue;
                Regex regex = m_sqlFilteRegexList[keyword];
                sql = sql.Substring(0,ignore.Length) + regex.Replace(sql.Substring(ignore.Length),1)">.Empty);
            }
        }
        #region 执行带参数的sql语句
        <param name="sqlString">string sqlString,1)">params DbParameter[] cmdParms)
        {
            DbConnection conn = m_Tran ==  GetCommand())
            {
                
                {
                    PrepareCommand(cmd,conn,m_Tran,sqlString,cmdParms);
                     cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                    <param name="strsql">string sqlString,1)"> DbParameter[] cmdParms)
        {
            DbConnection conn = GetCommand();
            
            {
                PrepareCommand(cmd,sqlString,cmdParms);
                DbDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                cmd.Parameters.Clear();
                 ex;
            }

        }
         GetCommand();
            PrepareCommand(cmd,cmdParms);
            using (DbDataAdapter da = GetDataAdapter(cmd))
            {
                DataSet ds = 
                {
                    da.Fill(ds,1)">);
                    cmd.Parameters.Clear();
                }
                
                {
                    cmd.dispose();
                    conn.Close();
                }
                #region PrepareCommand
        void PrepareCommand(DbCommand cmd,DbConnection conn,DbTransaction trans,1)"> cmdText,DbParameter[] cmdParms)
        {
             ConnectionState.Open) conn.open();
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            if (trans !=  trans;
            cmd.CommandType = CommandType.Text;
            if (cmdParms != )
            {
                foreach (DbParameter parm  cmdParms)
                {
                    cmd.Parameters.Add(parm);
                }
            }
        }
        #region 增删改查
        #region 获取最大编号
         获取最大编号
        <typeparam name="T">实体Model</typeparam>
        <param name="key">主键int GetMaxID<T>( key)
        {
            Type type = typeof(T);

            string sql = ;
            :
                    sql = string.Format(SELECT Max({0}) FROM {1}SELECT Max(cast({0} as int)) FROM {1}using (IDbCommand cmd = GetCommand(sql,1)">1int.Parse(obj.ToString()) + #region 添加
         添加
        void Insert( obj)
        {
            Insert(obj,m_AutoIncrement);
        }
        object obj,1)">bool autoIncrement)
        {
            StringBuilder strsql =  StringBuilder();
            Type type = obj.GetType();
            strsql.Append(insert into {0}( GetEntityProperties(type);
            List<string> propertyNameList = new List<string>();
            int savedCount = foreach (PropertyInfo propertyInfo  propertyInfoList)
            {
                if (propertyInfo.GetCustomAttributes(typeof(IsIdAttribute),1)">false).Length > 0 && type.GetCustomAttributes(typeof(AutoIncrementAttribute),1)">0) 0 && propertyInfo.GetCustomAttributes(0 && autoIncrement) ;

                typeof(IsDBFieldAttribute),1)">)
                {
                    propertyNameList.Add(propertyInfo.Name);
                    savedCount++;
                }
            }

            strsql.Append({0})string.Join(sql.Append( values ({0})string>(a => m_ParameterMark + a).ToArray())));
            DbParameter[] parameters =  DbParameter[savedCount];
            int k = for (int i = 0; i < propertyInfoList.Length && savedCount > 0; i++)
            {
                PropertyInfo propertyInfo = propertyInfoList[i];
                )
                {
                    object val = propertyInfo.GetValue(obj,1)">);
                    DbParameter param = GetDbParameter(m_ParameterMark + propertyInfo.Name,val ==  dbnull.Value : val);
                    parameters[k++] = param;
                }
            }

            Executesql(strsql.ToString(),parameters);
        }
        #region 修改
         修改
        void Update( obj)
        {
            object oldobj = Find(obj,1)">);
            if (oldobj == null) new Exception(无法获取到旧数据);

            StringBuilder strsql = update {0} object oldVal = propertyInfo.GetValue(oldobj,1)">);
                    if (!.Equals(oldVal,val))
                    {
                        propertyNameList.Add(propertyInfo.Name);
                        savedCount++;
                    }
                }
            }

            strsql.Append( set ));
            DbParameter[] parameters =  DbParameter[savedCount];
            StringBuilder sbPros =  StringBuilder();
             {0}={1}{0},propertyInfo.Name,m_ParameterMark));
                        DbParameter param = GetDbParameter(m_ParameterMark + propertyInfo.Name,1)"> dbnull.Value : val);
                        parameters[k++] = param;
                    }
                }
            }
            if (sbPros.Length > )
            {
                strsql.Append(sbPros.ToString());
            }
            strsql.Append( where {0}='{1}'if (savedCount > )
            {
                Executesql(strsql.ToString(),parameters);
            }
        }
        #region 删除
         根据Id删除
        void Delete<T>(int id)
        {
            Type type = (T);
            StringBuilder sbsql =  StringBuilder();
            DbParameter[] cmdParms = new DbParameter[];
            cmdParms[0] = GetDbParameter(m_ParameterMark + GetIdName(type),id);
            sbsql.Append(delete from {0} where {2}={1}{2}arameterMark,GetIdName(type)));

            Executesql(sbsql.ToString(),cmdParms);
        }
         根据Id集合删除
        void BatchDelete<T>( ids)
        {
            if (string.IsNullOrWhiteSpace(ids)) ;

            Type type = string[] idArr = ids.Split('');
            DbParameter[] cmdParms =  DbParameter[idArr.Length];
            sbsql.AppendFormat(delete from {0} where {1} in (0; i < idArr.Length; i++)
            {
                cmdParms[i] = GetDbParameter(m_ParameterMark + GetIdName(type) + i,idArr[i]);
                sbsql.AppendFormat({1}{2}{3},GetIdName(type),i);
            }
            sbsql.Remove(sbsql.Length - 1,);
            sbsql.Append());

            Executesql(sbsql.ToString(),1)"> 根据条件删除
         conditions)
        {
            string.IsNullOrWhiteSpace(conditions))  StringBuilder();
            sqlFilter( conditions);
            sbsql.Append(delete from {0} where {1}sql(sbsql.ToString());
        }
        #region 获取实体
        #region 根据实体获取实体
         根据实体获取实体
        object Find(bool readCache = )
        {
            Type type = obj.GetType();

            object result = Activator.CreateInstance(type);
            bool hasValue = ;
            IDataReader rd = select * from {0} where {2}='{1}'
            {
                rd = ExecuteReader(sql);

                PropertyInfo[] propertyInfoList = GetEntityProperties(type);

                int fcnt = rd.FieldCount;
                List<string> fileds = ();
                0; i < fcnt; i++)
                {
                    fileds.Add(rd.GetName(i).toupper());
                }

                while (rd.Read())
                {
                    hasValue = ;
                    IDataRecord record = rd;

                    foreach (PropertyInfo pro  propertyInfoList)
                    {
                        if (!fileds.Contains(pro.Name.toupper()) || record[pro.Name] == dbnull.Value)
                        {
                            ;
                        }

                        pro.SetValue(result,record[pro.Name] == dbnull.Value ? null : getReaderValue(record[pro.Name],pro.PropertyType),1)">);
                    }
                }
            }
             ex;
            }
            if (rd != null && !rd.IsClosed)
                {
                    rd.Close();
                    rd.dispose();
                }
            }

            if (hasValue)
            {
                 result;
            }
            ;
            }
        }
        #region 根据Id获取实体
         根据Id获取实体
        object FindById(Type type,1)"> id)
        {
             Activator.CreateInstance(type);
            IDataReader rd = static T FindById<T>(string id) where T : ()
        {
            Type type = (T);
            T result = (T)Activator.CreateInstance(type);
            IDataReader rd = default(T);
            }
        }
        #region 根据sql获取实体
         根据sql获取实体
        static T FindBysql<T>(string sql) string sql,1)">params DbParameter[] args)  ExecuteReader(sql,args);

                PropertyInfo[] propertyInfoList =#region 获取列表
         获取列表
        static List<T> FindListBysql<T>(()
        {
            List<T> list = new List<T> obj;
            IDataReader rd =  ExecuteReader(sql);

                typeof(T) == typeof())
                {
                     (rd.Read())
                    {
                        list.Add((T)rd[]);
                    }
                }
                else 
                {
                    PropertyInfo[] propertyInfoList = ((T)).GetProperties();

                     rd.FieldCount;
                    List<();
                    )
                    {
                        fileds.Add(rd.GetName(i).toupper());
                    }

                     (rd.Read())
                    {
                        IDataRecord record = rd;
                        obj =  T();


                         propertyInfoList)
                        {
                             dbnull.Value)
                            {
                                ;
                            }

                            pro.SetValue(obj,1)">);
                        }
                        list.Add((T)obj);
                    }
                }
            }
             list;
        }
        params DbParameter[] cmdParms) #region 分页获取列表
         分页(任意entity,尽量少的字段)
        static PagerModel FindPageBysql<T>(string orderby,1)">int pageSize,1)">int currentPage) ()
        {
            PagerModel pagerModel =  PagerModel(currentPage,pageSize);

            using (DbConnection connection = GetConnection())
            {
                connection.open();
                IDbCommand cmd = ;
                StringBuilder sb =  StringBuilder();
                string commandText = int startRow = int endRow =  (m_DBType)
                {
                    :
                        #region 分页查询语句
                        commandText = select count(*) from ({0}) Tsql);
                        cmd = GetCommand(commandText,connection);
                        pagerModel.totalRows = .Parse(cmd.ExecuteScalar().ToString());

                        startRow = pageSize * (currentPage - );
                        endRow = startRow + pageSize;

                        sb.Append(select * from ( select row_limit.*,rownum rownum_ from ();
                        sb.Append(sql);
                        string.IsNullOrWhiteSpace(orderby))
                        {
                            sb.Append(" );
                            sb.Append();
                        }
                        sb.Append( ) row_limit where rownum <= );
                        sb.Append(endRow);
                        sb.Append( ) where rownum_ >);
                        sb.Append(startRow);
                        #endregion
                        ;
                    1) + ;
                        endRow = startRow + pageSize - ;

                        sb.Append(@"
                            select * from 
                            (select ROW_NUMBER() over({1}) as rowNumber,t.* from ({0}) t) tempTable
                            where rowNumber between {2} and {3} sql,startRow,endRow));
                        );

                        sb.Append(select * from ();
                        }
                        sb.AppendFormat( ) row_limit limit {0},{1});

                        sb.Append(sql);
                         limit {0} offset {1}.Parse(cmd.ExecuteScalar().ToString());

                        endRow = pageSize * currentPage;
                        startRow = pageSize * currentPage > pagerModel.totalRows ? pagerModel.totalRows - pageSize * (currentPage - ) : pageSize;
                        if (startRow <= 0) { pagerModel.result = new List<T>();  pagerModel; }
                        string[] orderbyArr = {0} ascorderby.Trim()).Split(' );

                        sb.AppendFormat(
                            select * from(
                            select top {4} * from 
                            (select top {3} * from ({0}) order by {1} asc)
                            order by {1} desc
                            ) order by {1} {2}0],1)">],endRow,1)">;
                }

                List<T> list = FindListBysql<T>(sb.ToString());
                pagerModel.result = list;
            }

             pagerModel;
        }
        <typeparam name="T"></typeparam>
        <param name="sql"></param>
        <returns></returns>
        int currentPage,connection);
                         cmdParms) cmd.Parameters.Add(parm);
                        pagerModel.totalRows = .Parse(cmd.ExecuteScalar().ToString());
                        cmd.Parameters.Clear();

                        endRow = pageSize *(sb.ToString(),cmdParms);
                pagerModel.result = pagerModel;
        }


        static DataSet FindPageBysql(out int totalCount,1)"> DbParameter[] cmdParms)
        {
            DataSet ds = ;
                totalCount =  cmdParms) cmd.Parameters.Add(parm);
                        totalCount =  currentPage;
                        startRow = pageSize * currentPage > totalCount ? totalCount - pageSize * (currentPage - 0) { ; }
                        ;
                }

                ds = Query(sql,cmdParms);
            }
             ds;
        }
        #region getReaderValue 转换数据
         转换数据
         Object getReaderValue(Object rdValue,Type ptype)
        {
            if (ptype == double))
                 Convert.Todouble(rdValue);

            decimal Convert.ToDecimal(rdValue);

             Convert.ToInt32(rdValue);

            long Convert.ToInt64(rdValue);

            (DateTime))
                 Convert.ToDateTime(rdValue);

            typeof(Nullable<double>decimal>int>long>typeof(Nullable<DateTime> rdValue;
        }
        #region 获取主键名称
         获取主键名称
         GetIdName(Type type)
        {
            PropertyInfo[] propertyInfoList = GetEntityProperties(type);
             propertyInfo.Name;
                }
            }
            Id#region 获取主键值
        object GetIdVal( val)
        {
            string idName = GetIdName(val.GetType());
            .IsNullOrWhiteSpace(idName))
            {
                return val.GetType().GetProperty(idName).GetValue(val,1)">);
            }
            #region 获取实体类属性
         获取实体类属性
         PropertyInfo[] GetEntityProperties(Type type)
        {
            List<PropertyInfo> result = new List<PropertyInfo>();
            PropertyInfo[] propertyInfoList = type.GetProperties();
            typeof(EdmRelationshipNavigationPropertyAttribute),1)">false).Length == 0
                    && propertyInfo.GetCustomAttributes(typeof(browsableAttribute),1)">)
                {
                    result.Add(propertyInfo);
                }
            }
             result.ToArray();
        }
        #region 获取基类
         获取基类
         Type GetBaseType(Type type)
        {
            while (type.BaseType != null && type.BaseType.Name != (Object).Name)
            {
                type = type.BaseType;
            }
             type;
        }
        #region 事务
        #region 开始事务
         开始事务
        void BeginTransaction()
        {
            DbConnection conn = GetConnection();
             ConnectionState.Open) conn.open();
            m_Tran = conn.BeginTransaction();
        }
        #region 提交事务
         提交事务
         CommitTransaction()
        {
            return; //防止重复提交
            DbConnection conn = m_Tran.Connection;
            
            {
                m_Tran.Commit();
            }
             (Exception ex)
            {
                m_Tran.Rollback();
            }
            if (conn.State == ConnectionState.Open) conn.Close();
                m_Tran.dispose();
                m_Tran = #region 回滚事务(出错时调用方法回滚)
         回滚事务(出错时调用方法回滚)
         RollbackTransaction()
        {
            防止重复回滚
            DbConnection conn = m_Tran.Connection;
            m_Tran.Rollback();
             ConnectionState.Open) conn.Close();
        }
        #endregion

    }
}
View Code

sqlString类代码(更方便的参数化查询):

 System.Linq;
 System.Threading.Tasks;
 System.Configuration;

 参数化查询sql字符串
     sqlString
    {
        #region 变量属性
        ];

        private StringBuilder _sql =  StringBuilder();

        private List<DbParameter> _paramList = new List<DbParameter>();

        private Regex _regex = [@|:]([\w]+)noreCase);

         参数化查询的参数
        public DbParameter[] Params { get {  _paramList.ToArray(); } }

         参数化查询sql
        string sql {  _sql.ToString(); } }
        #region 构造函数
        public sqlString(params [] args)
        {
            Appendsql(sql,args);
        }
        #region Appendsql
         追加参数化sql
        sql<param name="args">参数void Appendsql([] args)
        {
            Dictionary<object> dict = object>();
            MatchCollection mc = _regex.Matches(sql);
            foreach (Match m  mc)
            {
                string val1 = m.Groups[].Value;
                dict.ContainsKey(val1))
                {
                    dict.Add(val1,1)">);
                    sql = Replacesql(sql,m.Value,val1);
                }
            }

            if (args.Length < dict.Keys.Count) sqlString.AppendFormat参数不够);

            List<string> keyList = dict.Keys.ToList();
            0; i < keyList.Count; i++)
            {
                _paramList.Add(DBHelper.GetDbParameter(keyList[i],args[i]));
            }

            _sql.Append(sql);
        }
        #region AppendFormat
         封装StringBuilder AppendFormat 追加非参数化sql
        void AppendFormat([] args)
        {
            if (_regex.IsMatch(sql)) 追加参数化sql请使用Appendsql);
            _sql.AppendFormat(sql,1)">#region ToString
        override  ToString()
        {
             _sql.ToString();
        }
        #region Replacesql
        string Replacesql(string oldStr,1)"> name)
        {
            string newStr = DBHelper.GetParameterMark() + name;
             sql.Replace(oldStr,newStr);
        }
        

    }
}
View Code

说明:DBHelper中对事务变量private static DbTransaction m_Tran使用了[ThreadStatic]标签,以支持用户并发;但是如果是单个用户使用多线程并发请求服务器,可能这种方式的数据库事务是不支持的,不过一般项目没有这种需求,如果有请使用HttpContext.Current.Items改写或者其它方法改写。

Web.config配置:

<connectionStrings>
  add name="DefaultConnection"  connectionString="server=localhost;database=netcms3.0;user id=root;password=root;character set=gbk;" />
</>
appSettings<!--数据库类型-->
  key="DBType" value="MysqL"/>
  数据库自增="AutoIncrement"="false">
View Code

说明:对于sql Server数据库,通过<add key="AutoIncrement" value="false"/>来设置是否使用数据库自增。

DBHelper类库需要引用的程序集:

除VS2012自带的DLL外需要的DLL:

MysqL.Data.dll

System.Data.sqlite.dll

其中Models类库如下:

说明:Models目录中的类及其属性数据库中的表和字段是完全对应的,Models全部由生成生成,并且不允许手动修改。ExtModels目录中的类是扩展类,主要用于查询显示,比如表中存的是code,但你需要关联查询另一张表中的name,就可以在这个扩展类中扩展一个用于显示的name字段。Models和ExtModels目录的中类都是partial修饰。

PagerModel类:

 System.Collections;
 System.Web;

 Models
{
     分页
     PagerModel
    {
        #region 字段
         当前页数
        int page { get; set; }
         每页记录数
        int rows {  排序字段
        string sort {  排序的方式asc,desc
        string order {  记录
        object result {  记录数
        int totalRows { ; }
        public PagerModel()
        {

        }
        /// 
        <param name="page">当前页数<param name="rows">每页记录数public PagerModel(int page,1)"> rows)
        {
            this.page = page;
            this.rows = rows;
        }
        #region 扩展字段
         总页数
         pageCount
        {
            getreturn (totalRows - 1) / rows + ;
            }
        }
         上一页
         prePage
        {
            if (page - 1 > return page - ;
                }
                 下一页
         nextPage
        {
            if (page + 1 < pageCount)
                {
                    return page +  pageCount;
            }
        }
        

    }
}
View Code

IsIdAttribute类:

 System.Text;

 标识该属性是主健
    </summary>
    [Serializable,AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
     IsIdAttribute : Attribute
    {
    }
}
View Code

IsDBFieldAttribute类:

 标识该属性数据库字段
     IsDBFieldAttribute : Attribute
    {
    }
}
View Code

AutoIncrementAttribute类(可以加在主键字段上,也可以加在类上):

 System.Threading.Tasks;

 标识该属性是自增字段 或 标识该类的主键是自增字段
     AutoIncrementAttribute : Attribute
    {
    }
}
View Code

Models示例:

 System.Linq;

 内容详情
        [Serializable]
    partial  cms_content
    {
         编号
                [IsId]
        [IsDBField]
        int id {  所属栏目ID
                [IsDBField]
        int? channelId {  标题
        string title {  内容
        string contents {  作者
        string author {  阅读次数
        int? readCount {  发布时间
        public DateTime? publishTime {  发布者
        int? publishUserId {  审核(0待审1通过2不通过)
        int? audit {  审核人
        int? auditUserId {  审核时间
        public DateTime? auditTime {  页面关键词
        string keywords {  页面描述
        string description {  页面链接
        string pageUrl {  内容封面
        string imgurl {  是否链接(0否1是)
        int? isPageUrl {  模板(模板文件名,例:content.html)
        string template {  推荐(1推荐0不推荐)
        int? recommend { ; }
    }
}
View Code

ExtModels示例:

 栏目名称
        string channelName {  用户显示string showName {  审核状态
         dispAudit
        {
            switch (this.audit ?? 待审核审核通过2审核不通过error { }
        }
         在当前页中的索引
        int curPageSort {  是否为空,模板使用,0不为空1为空
        int isNull { ; }
    }
}
View Code

如何使用:

说明:支持参数化的增删改查,推荐使用参数化的增删改查;非参数化的增删改查过滤了部分数据库关键字以防止sql注入,但可能仍然不安全。下面例子中的添加修改、根据ID删除、根据ID集合批量删除都是参数化的,示例中的查询和其它方式的删除不是参数化的,DBHelper提供了相关的参数化查询和执行sql

添加

<summary>
 添加
 obj)
{
    DBHelper.Insert(obj);
}
View Code

说明:sql Server数据库可以使用自增,Oracle数据库可以使用Sequence,小系统可以使用DBHelper自带的GetMaxID方法

获取最大ID(当然,ID一般采用自增,对于并发量极少的系统,或单机系统,为了省事,可以这样做):

 GetMaxId
 GetMaxId()
{
    return DBHelper.GetMaxID<BS_Template>(id);
}
View Code

修改

 修改
 obj)
{
    DBHelper.Update(obj);
}
View Code

删除

根据ID删除

 删除
void Del( id)
{
    DBHelper.Delete<BS_Template>(id);
}
View Code

根据ID集合批量删除

void BatchDelete( ids)
{
    DBHelper.BatchDelete<BS_Template>(ids);
}
View Code

根据条件删除

void Delete( conditions)
{
    DBHelper.Delete<BS_Template>(conditions);
}
View Code

其它方式的删除请使用:

public static int Executesql(string sqlString)

根据ID查询实体:

public cms_content Get( id)
{
    return DBHelper.FindById<cms_content>(id.ToString());
}
View Code

查询

public List<cms_content> GetListAll()
{
    StringBuilder sql = new StringBuilder(
        select content.*,channel.title as channelName,user.showName
        from cms_content content
        left join cms_channel channel on channel.id=content.channelId
        left join CMS_sys_user user on user.id=content.publishUserId
        where content.audit=1 
        order by publishTime desc,id desc));

    return DBHelper.FindListBysql<cms_content>(sql.ToString());
}
View Code

说明:ExtModels下的扩展Model,可以支持查询数据库中不存在的字段,并映射填充到实体类

分页查询

public List<cms_content> GetList(ref PagerModel pager,1)">int channelId,1)">string title,1)"> audit)
{
    StringBuilder sql = if (channelId != -)
    {
        sql.AppendFormat( and content.channelId = {0}.IsNullOrWhiteSpace(title))
    {
        sql.AppendFormat( and content.title like '%{0}%'if (audit != - and content.audit = {0}orderby = order by content.publishTime desc,1)">);
    pager = DBHelper.FindPageBysql<cms_content>(sql.ToString(),pager.rows,pager.page);
    return pager.result as List<cms_content>;
}
View Code

数据库事务:


{
    DBHelper.BeginTransaction(); 开启数据库事务

    在这里写增删改操作

    DBHelper.CommitTransaction(); 提交数据库事务
}(Exception ex)
{
    DBHelper.RollbackTransaction(); 回滚数据库事务
}
View Code

DAL层增删改查示例:

 DBUtil;
 DAL
{
     内容详情管理
     ContentDal
    {
         audit)
        {
            StringBuilder sql = 
                select content.*,user.showName
                from cms_content content
                left join cms_channel channel on channel.id=content.channelId
                left join CMS_sys_user user on user.id=content.publishUserId
                where 1=1 ));

            )
            {
                sql.AppendFormat(.IsNullOrWhiteSpace(title))
            {
                sql.AppendFormat();
            pager = DBHelper.FindPageBysql<cms_content>(sql.ToString(),pager.page);
            <param name="pager">分页<param name="channel">栏目,可以是栏目ID或栏目名称<param name="where">where语句string channel,1)">where)
        {
            StringBuilder sql = ))
            {
                sql.AppendFormat( and {0});
            }

            .IsNullOrWhiteSpace(channel))
            {
                ChannelDal channelDal =  ChannelDal();
                if (Regex.IsMatch(channel,1)">^\d+$")) 数字,即栏目ID
                {
                    string channelIds = channelDal.GetChildIds(Convert.ToInt32(channel));
                    sql.AppendFormat( and channelId in ({0})非数字,即栏目名称
 channelDal.GetChildIds(channel);
                    sql.AppendFormat(order by publishTime desc,1)">if (pager.rows > )
            {
                PagerModel pagerModel = DBHelper.FindPageBysql<cms_content>(sql.ToString(),pager.page);
                pager.totalRows = pagerModel.totalRows;
                pager.result = pagerModel.result;
                List<cms_content> list = pagerModel.result ;
                list.ForEach(a =>
                {
                    a.curPageSort = i++;
                });
                return pagerModel.result return DBHelper.FindListBysql<cms_content>(sql.ToString() + );
            }
        }
         GetListAll()
        {
            StringBuilder sql = (sql.ToString());
        }
        #region 获取总数
         获取总数
         GetAllCount()
        {
            StringBuilder sql = 
                select count(*)
                from cms_content content
                where content.audit=1 Convert.ToInt32(DBHelper.GetSingle(sql.ToString()));
        }
        #region 获取
         获取
        (id.ToString());
        }
         根据channelId获取一条内容详情
        public cms_content GetByChannelId( channelId)
        {
            return DBHelper.FindBysql<cms_content>(select * from cms_content where channelId={0} and audit=1public cms_content GetNext( id)
        {
            cms_content current = Get(id);
            select * from cms_content where id<{0} and channelId={1} and audit=1 order by id desc limit 0,1public cms_content GetPre(select * from cms_content where id>{0} and channelId={1} and audit=1 order by id asc limit 0,current.channelId));
        }
         Insert(cms_content model)
        {
            model.id = DBHelper.GetMaxID<cms_content>();
            DBHelper.Insert(model);
        }
         Update(cms_content model)
        {
            DBHelper.Update(model);
        }
         删除
         ids)
        {
            DBHelper.BatchDelete<cms_content>(ids);
        }
        

    }
}
View Code

使用sqlString类实现更加方便的参数化查询

 Models;
 DAL
{
     TestMysqLDal
    {
        #region 获取集合 (参数化查询)
         获取集合
        public List<utils_test> GetList3( name,DateTime startTime,DateTime endTime)
        {
            sqlString sql = new sqlString(
                select *
                from utils_test t
                where 1=1 );

            sql.Appendsql( and name like @name%" + name +  and (add_time between @startTime and @endTime)yyyy-MM-dd HH:mm:ss"),endTime.ToString());

            List<utils_test> result = DBHelper.FindListBysql<utils_test>(sql.sql,sql.Params);
             result;
        }
        #region 获取集合 (参数化非参数化混合查询)
        public List<TWO_ORDER> GetList(int? status)
        {
            sqlString sql = 
                select *
                from two_order t
                where 1=1 
                and DEL_FLAG=@delFlag0 
                and (
                    ORDER_TIME>=STR_TO_DATE(@startTime,'%Y-%m-%d %H:%i:%s') 
                    and ORDER_TIME<=STR_TO_DATE(@endTime,'%Y-%m-%d %H:%i:%s')
                ).IsNullOrWhiteSpace(name))
            {
                sql.Appendsql( and PRISONER_NAME like @nameif (status != )
            {
                sql.Appendsql( and T_STATUS = @statussql.Appendsql( and 1=1"); 测试没有参数

            sql.Appendsql( order by ORDER_TIME desc,ID asc测试排序

            List<TWO_ORDER> result = DBHelper.FindListBysql<TWO_ORDER>#region 分页获取集合 (参数化非参数化混合查询)
         分页获取集合 
        public List<TWO_ORDER> GetListPage(new sqlString(
                select *
                from two_order t
                where 1=1 
                and DEL_FLAG='{0}'));

            sql.Appendsql( and T_STATUS = '{0}'测试追加非参数化sql
            }

            sql.Appendsql(测试没有参数

            orderby = order by ORDER_TIME desc,1)">"; 测试排序
            pager = DBHelper.FindPageBysql<TWO_ORDER>(sql.sql,pager.page,1)">as List<TWO_ORDER> obj)
        {
            DBHelper.Insert(obj);
        }
        #region 查询单个记录 (参数化查询)
         查询单个记录
        public utils_test Get( name)
        {
            sqlString sql = 
                select *
                from utils_test t
                where 1=1 
                and name=@namesql<utils_test>

    }
}
View Code

例子代码下载:https://files.cnblogs.com/files/s0611163/DBHelperDemo.zip

说明:例子程序是Winform,该DBHelper也适用于Web项目。

配套Model生成器下载:

链接: https://pan.baidu.com/s/1QR7fjXvNyQKGzZ2_2XV0AQ 提取码: kgsq

https://files.cnblogs.com/files/s0611163/Model%E7%94%9F%E6%88%90%E5%99%A8.zip

 

如果您不明白我为什么要写DBHelper,为什么没有语法糖,为什么查询分页查询要使用原生sql,看看下面我们ERP项目中的代码,你会明白,当然,这个项目设计的确实不好:

1、

 统计sql
string GetReportsql( formData)
{
    ProductInvoiceModel search = JsonConvert.DeserializeObject<ProductInvoiceModel>(formData);

    StringBuilder sql = 
        select * from 
        (select distinct 
        '出库单' as '报表类型',pos.billNo as '单据编号',pos.projectCode as '项目编号',pro.projectName as '项目名称',ma.subProject as '项目子项',case when cs.conMemberCode is not NULL then cs.conMemberCode else mat.materialCode end as '构件编码',case when cmd.memberName is not NULL then cmd.memberName else mat.materialName end as '材料名称',case when cs.conMemberCode is not NULL then '构件' else '物料' end as '类型',mad.model as '规格型号',dic1.dicItem as '单位',posd.qty as '数量',CONVERT(varchar(100),pos.billDate,23) as '日期'
                
        from Pro_ProductOutStorageDet posd
        left join Pro_ProductOutStorage pos on pos.id=posd.parentId

        left join Pro_MatAllotDet mad on posd.matAllotDetId=mad.id
        left join Pro_MatAllot ma on ma.id=mad.parentID and ma.status=2
        left join Pro_MatStock ms on ms.id=mad.matStockId and mad.memberType=1
        left join Pro_ConStock cs on cs.id=mad.matStockId and mad.memberType=0
        left join sys_material mat on mat.materialCode=ms.materailCode

        left join Pro_ProductInstorage pi on pi.billNo=cs.billNo
        left join Pro_ProductInstorageDet pid on pid.parentId=pi.id

        left join Pro_ConMember cm on cm.billCode=pi.conMemberBillNo
        left join Pro_ConMemberDet cmd on cmd.id=pid.conMemberDetId

        left join Pro_Info pro on pos.projectCode=pro.projectNum

        left join sys_dicDetail dic1 on dic1.dicItemcode=mad.unitCode  

        union all

        select distinct 
        'XXX出库单' as '报表类型','' as '项目子项',case when cmd.model is not NULL then cmd.model else mat.model end as '规格型号',case when dic1.dicItem  is not NULL then dic1.dicItem  else dic2.dicItem  end as '单位',23) as '日期'
                
        from Pro_ProductOut2StorageDet posd
        left join Pro_ProductOut2Storage pos on pos.id=posd.parentId

        left join Pro_MatStock ms on ms.id=posd.matStockId
        left join Pro_ConStock cs on cs.id=posd.conInventoryDetId
        left join sys_material mat on mat.materialCode=ms.materailCode

        left join Pro_ProductInstorage pi on pi.billNo=cs.billNo
        left join Pro_ProductInstorageDet pid on pid.parentId=pi.id

        left join Pro_ConMember cm on cm.billCode=pi.conMemberBillNo
        left join Pro_ConMemberDet cmd on cmd.id=pid.conMemberDetId

        left join Pro_Info pro on pos.projectCode=pro.projectNum

        left join sys_dicDetail dic1 on dic1.dicItemcode=mat.unitCode  
        left join sys_dicDetail dic2 on dic2.dicItemcode=cmd.qtyUnit  

        union all

        select distinct 
        '生产消耗单' as '报表类型',pc.billCode as '单据编号',pro.projectNum as '项目编号',ll.subProject as '项目子项',pcd.consumeQty as '数量',pc.billDate,23) as '日期'
                
        from Pro_ProductConsume pc
        left join Pro_ProductConsumeDet pcd on pcd.parentId=pc.id

        left join Pro_LingLiaoDet lld on lld.id=pcd.lingLiaoDetId
        left join Pro_LingLiao ll on ll.id=lld.parentId

        left join Pro_MatStock ms on ms.id=lld.matStockId and lld.memberType=1
        left join Pro_ConStock cs on cs.id=lld.matStockId and lld.memberType=0
        left join sys_material mat on mat.materialCode=ms.materailCode

        left join Pro_ProductInstorage pi on pi.billNo=cs.billNo
        left join Pro_ProductInstorageDet pid on pid.parentId=pi.id

        left join Pro_ConMember cm on cm.billCode=pi.conMemberBillNo
        left join Pro_ConMemberDet cmd on cmd.id=pid.conMemberDetId

        left join Pro_ProTask pt on pt.billCode=ll.proTaskCode
        left join Pro_Info pro on pt.proInfCode=pro.billCode

        left join sys_dicDetail dic1 on dic1.dicItemcode=mat.unitCode  
        left join sys_dicDetail dic2 on dic2.dicItemcode=cmd.qtyUnit  
        ) T where 1=1 .IsNullOrEmpty(search.projectName))
    {
        sql.AppendFormat(  and T.项目名称 like '%{0}%' .IsNullOrEmpty(search.projectCode))
    {
        sql.AppendFormat(  and T.项目编号 like '%{0}%' string.IsNullOrEmpty(search.btime) && !.IsNullOrEmpty(search.etime))
    {
        sql.AppendFormat( and  T.日期  >=  '{0}' and  T.日期  <=  '{0}' sql.ToString();
}
View Code

说明:查询sql书写规范:sql不能写的乱七八糟,该换行换行,该对齐对齐。

2、

        public List<MatAllotModel> GeProMatAllotList(string billCode,1)">string projectNum,1)">string projectName,1)">string remarks,1)"> status)
        {
            string sql = select v.*,ISNULL(v.IsFinish,(case when ISNULL(v.pqty,0)= ISNULL(v.mqty,0) then 1 else 0 end)) as IsEnd from (
select ma.*,e.name + '('+isnull(e.mobilephone,'')+')' as billCreatorName,i.projectName,s.storeHouseName as inStoreName,(select stuff((select distinct ','+s.storeHouseName from Pro_MatAllotDet mad
join sys_storehouse s on mad.outStorageCode=s.storeHouseCode
where parentId =ma.id for xml path('')),1,'')) as outStoreName,I.projectSim,D.dicItem AS typename,ppi.id as InvoiceId,i.projectNum,(select sum(md.qty) from Pro_MatAllotDet md  where md.parentId =ma.id) as mqty,(select sum(qty) from Pro_ProductOutStorageDet pod 
left join Pro_ProductOutStorage po on po.id = pod.parentID
where po.matAllotBillCode = ma.billCode) as pqty
from Pro_MatAllot ma
join sys_storehouse s on ma.inStoreCode=s.storeHouseCode
join sys_employee e on ma.billCreator=e.employeeCode
left join Pro_ProductInvoice ppi on ppi.MatAllotBillCode=ma.billCode
left join Pro_Info i on ma.projectCode = i.projectNum
LEFT JOIN sys_dicDetail D ON D.dicItemcode = I.projectType
) as v where 1=1 .IsNullOrEmpty(billCode))
            {
                sql +=  and v.billCode like '%" + billCode.Trim() + %'.IsNullOrEmpty(projectName))
            {
                sql +=  and v.projectName like '%" + projectName.Trim() + .IsNullOrEmpty(projectNum))
            {
                sql +=  and v.projectNum like '%" + projectNum.Trim() + .IsNullOrEmpty(remarks))
            {
                sql +=  and v.remarks like '%" + remarks.Trim() + ;
            }
            sql +=  and v.status=" + status + "";
            List<MatAllotModel> matAllot = EntityHelper.Default.GetPageEntities<MatAllotModel>(pager.page,pager.sort,pager.order);
            pager.totalRows = DBHelper.Default.Count(sql);
            pager.result = matAllot;
             matAllot;
        }
View Code

3、

static List<ConStockDialogMod> GetMaterialData(string memberName,1)">string storeCode,1)">string parentId,1)"> store)
{
    StringBuilder where = new StringBuilder( and 1=1 );
    string.IsNullOrEmpty(memberName))              当物料为空时,查询出所有的结果集,否则查询出此种相似物料的结果集
        where.AppendFormat(  and t3.memberName like '%{0}%' string.IsNullOrEmpty(storeCode))                and SSH.storeHouseCode='{0}' string.IsNullOrEmpty(parentId))                and t3.parentId = {0} .IsNullOrEmpty(store))
          and SSH.storeHouseName like '%{0}%'  SELECT PM.id,PM.conMemberCode as conMemberCode,PM.price,(PM.qty-PM.lockQty-PM.usedQty) AS stockNum,PM.instoreTime,PM.billNo,PM.storeCode,PM.lockQty,PM.usedQty,SSH.storeHouseName AS storeName,t3.allWeight,t3.qtyUnit,t3.weight as weights,t3.memberName,t3.model,t3.qulity,d1.dicItem as allWeightUnitName,d2.dicItem as qtyUnitName,d3.dicItem as qulityName,d4.dicItem as weightUnitName,(select SUM(pt.qty) from Pro_ProductOutstorageDet pt where pt.conInventoryDetId=PM.id)as outQty  
        from Pro_ConStock PM
        join Pro_ConPurInstore cpd on PM.billNo=cpd.billCode
        join Pro_ConPurInstoreDet cp on cpd.id=cp.parentId and PM.billId=cp.id
        join dbo.Pro_ConGoodsDet t on t.id=cp.conGoodsDetId
        join dbo.Pro_ConPurchaseContractDet t1 on t1.id=t.conContractDetId
        join dbo.Pro_ConPurchasePlanDet t2 on t2.id=t1.conPlanDetID
        join dbo.Pro_ConMemberDet t3 on t3.id=t2.conMemberDetId
        left join sys_storehouse SSH on SSH.storeHouseCode=PM.storeCode
        left join sys_dicDetail d1 on d1.dicItemcode=t3.allWeightUnit
        left join sys_dicDetail d2 on d2.dicItemcode=t3.qtyUnit
        left join sys_dicDetail d3 on d3.dicItemcode=t3.qulity
        left join sys_dicDetail d4 on d4.dicItemcode=t3.weightUnit 
        WHERE  PM.qty-PM.lockQty-PM.usedQty > 0  " + where +
     union 
        SELECT PM.id,(select SUM(pt.qty) from Pro_ProductOutstorageDet pt where pt.conInventoryDetId=PM.id)as outQty  
        from Pro_ConStock PM
        join Pro_ProductInstorage cpd on PM.billNo=cpd.billNo
        join Pro_ProductInstorageDet cp on cpd.id=cp.parentId and PM.billId=cp.id
        join dbo.Pro_ConMemberDet t3 on t3.id=cp.conMemberDetId
        left join sys_storehouse SSH on SSH.storeHouseCode=PM.storeCode
        left join sys_dicDetail d1 on d1.dicItemcode=t3.allWeightUnit
        left join sys_dicDetail d2 on d2.dicItemcode=t3.qtyUnit
        left join sys_dicDetail d3 on d3.dicItemcode=t3.qulity
        left join sys_dicDetail d4 on d4.dicItemcode=t3.weightUnit  
        WHERE  PM.qty-PM.lockQty-PM.usedQty > 0 ;


    List<ConStockDialogMod> model = EntityHelper.Default.GetPageEntities<ConStockDialogMod>(pager.page,sql.ToString(),pager.order);
    pager.totalRows = DBHelper.Default.Count(sql.ToString());
    pager.result = model;
     model;

}
View Code

4、

         sql
        <param name="formData"></param>
         formData)
        {
            TaskAllocationModel search = JsonConvert.DeserializeObject<TaskAllocationModel>(formData);
            StringBuilder  where 1=1 .IsNullOrEmpty(search.projectCode))
            {
                  and ta.projectCode like '%{0}%' .IsNullOrEmpty(search.projectName))
            {
                  and pro.projectName like '%{0}%' select ta.billCode as '单号',ta.desingBillCode as '项目设计任务单',CASE ta.violent WHEN '1' THEN '是' ELSE '否' END as '是否加急',CASE ta.taskType WHEN '0' THEN '载荷图' WHEN '1' THEN '方案图' WHEN '2' THEN '工程量统计' ELSE '载荷图与工程量统计' END as '任务类型',ta.desingContent as '设计内容',ta.auditorscore as '审核人打分',(select e.RealName
from Wf2Operate oper 
left join Wf2Node n on n.id = oper.Wf2NoteID 
left join employee e on e.employeecode = oper.Operator 
where Wf2InstanceID = ta.LastWf2InstanceID and n.Name='设计' and oper.OperationID != -3) as '设计者',(select e.RealName
from Wf2Operate oper 
left join Wf2Node n on n.id = oper.Wf2NoteID 
left join employee e on e.employeecode = oper.Operator 
where Wf2InstanceID = ta.LastWf2InstanceID and n.Name='校对' and oper.OperationID != -3) as '校对者',(select e.RealName
from Wf2Operate oper 
left join Wf2Node n on n.id = oper.Wf2NoteID 
left join employee e on e.employeecode = oper.Operator 
where Wf2InstanceID = ta.LastWf2InstanceID and n.Name='审核' and oper.OperationID != -3) as '审核者',(select e.RealName
from Wf2Operate oper 
left join Wf2Node n on n.id = oper.Wf2NoteID 
left join employee e on e.employeecode = oper.Operator 
where Wf2InstanceID = ta.LastWf2InstanceID and n.Name='审定' and oper.OperationID != -3) as '审定者',e.name as '创建人',ta.creatTime as '创建时间'
from Pro_TaskAllocation ta
left join Pro_Info pro on ta.projectCode=pro.projectNum
left join sys_employee e on ta.creator=e.employeeCode 
                  sql.ToString();
        }
View Code

5、

            select t.*,t.haveQty as weichukuNum,(t.qty - t.chukuNum) as shenyuNum  from (SELECT o.*,(
 case memberType when 1 then (SELECT (qty- lockQty- usedQty) 
 FROM Pro_MatStock s where s.id=o.matStockId )
 when 0 then ((SELECT (qty- lockQty- usedQty) 
 FROM Pro_ConStock s where s.id=o.matStockId )) else 0 end) as haveQty,(case memberType when 1 then (SELECT materialName from sys_material where materialCode = o.code )
 when 0 then (select disTINCT memberName from Pro_ConMemberDet v LEFT join Pro_ConMember g on g.id=v.parentId where v.memberCode=o.code and g.billCode=ma.conMemberBillNo) else '' end) as materialName,sh.storeHouseName as outStorageName,isnull((case memberType when 1 then (select SUM(pt.qty) from Pro_ProductOutstorageDet pt LEFT join Pro_ProductOutstorage p on p.id=pt.parentID where pt.matStockId=o.matStockId and p.status in (1,2))
 when 0 then (select SUM(pt.qty) from Pro_ProductOutstorageDet pt LEFT join Pro_ProductOutstorage p on p.id=pt.parentID where pt.conInventoryDetId=o.matStockId and p.status in (1,2)) else 0 end),0) as chukuNum,(case memberType when 1 then (select SUM(ms.qty-ms.lockQty-ms.usedQty) from Pro_MatStock ms where ms.storeCode=ma.inStoreCode AND ms.materailCode =o.code)
 when 0 then (select SUM(cs.qty-cs.lockQty-cs.usedQty) from Pro_ConStock cs where cs.storeCode=ma.inStoreCode AND cs.conMemberCode =o.code) else 0 end) as xiangmukuNum
 from  Pro_MatAllotDet o 
 JOIN Pro_MatAllot ma on o.parentId = ma.id
 join sys_storehouse sh on o.outStorageCode=sh.storeHouseCode  
 where o.parentId in ({0})) t where t.chukuNum < t.qtyView Code

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐