一个控制台程序,MSSQL 2008 数据库,其中一个大表数据超过6000千万,开发时间有限不可能花很多时间设计、架构。使用控制台一是为了实现高效运行,二是程序是在服务器上定时运行无人干预。要保证程序可维护性和快速开发和程序高效运行,没时间去分层开发,直接使用了entity framework并结合ado.net对EF进行了扩展。不折腾是因为怕EF有性能问题使用了sqlbuckcopy进行批量插入数据,使用DB FIRST。重构是因为原来是oracle数据库,数据库已经改为MSSQL 2008。

1、解决方案、架构

解决方案:

2、业务说明

程序主要业务是读取指定目录下面的XML文件,将里面的文件里的记录整理拼凑为数据库里对应表的datatable,然后使用SqlBulkCopy批量插入数据库。文件是远程计算机通过FTP上传的。XML里面的记录和需要存储的数据库里对应表的表结构不一致,需要转换和补全。程序是定时运行,使用操作系统的计划任务进行调度。日志组件使用了log4net,来实现控制台显示和数据库记录日志。

3、关键代码和编码思路

1、业务逻辑实现

2、EF扩展类

using System.Data;
using System.Data.EntityClient;
using System;
using System.Data.SqlClient;
using System.Configuration;namespace XXX_App
{public partial class XXX_DBEntities : global::System.Data.Objects.ObjectContext{Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);/// <summary>/// 使用ado.net执行sqlbulkcopy/// </summary>/// <param name="dt"></param>/// <param name="efConnectStr">webconfig里的数据库连接字符串</param>/// <returns></returns>public bool ExecuteSqlBulkCopy(DataTable dt){string dbConnStr = this.GetEF_ConnectStr2Ado_ConnectStr();bool result = false;#region ado.net execute sqlbulkcopyusing (SqlConnection dbConn = new SqlConnection(dbConnStr)){try{#region 执行sqlbulkcopydbConn.Open();SqlCommand cmd = dbConn.CreateCommand();cmd.CommandText = "delete sc_productsource_temp";                    cmd.ExecuteNonQuery();new SqlBulkCopy(dbConn) {DestinationTableName = "sc_productsource_temp", BatchSize = dt.Rows.Count,BulkCopyTimeout = 1800}.WriteToServer(dt);#endregionresult = true;}catch (Exception ex){result = false;throw new Exception(ex.Message);}finally{if (result){#region 临时表流量明细记录转正式 SC_PRODUCTSOURCESqlCommand cmd = dbConn.CreateCommand();cmd.CommandText = " INSERT INTO  SC_PRODUCTSOURCE (PRODUCTSOURCEID,FACTORYID,PRDLINEID "+" ,MACRANDOMCODE    ,PRODUCTBATCHIDX ,LASERDNA_CODE ,PRODUCTNO ,PRODUCTNAME,PRODUCTTYPENAME"+" ,PRODUCTDATE ,PRINTCODEDT ,FACTORYSHIFTNO ,OUTBOX_DNACODE ,VIRTUALBALECODE" +" ,SENDTONDC_DT,FAC_NO,PRODUCTVERSION) " +" SELECT  NEWID() PRODUCTSOURCEID,FACTORYID,PRDLINEID,MACRANDOMCODE,PRODUCTBATCHIDX " +"      ,LASERDNA_CODE,PRODUCTNO,PRODUCTNAME,PRODUCTTYPENAME,PRODUCTDATE,PRINTCODEDT " +"      ,FACTORYSHIFTNO,OUTBOX_DNACODE,VIRTUALBALECODE,SENDTONDC_DT,FAC_NO,PRODUCTVERSION " +" FROM sc_productsource_temp";         cmd.ExecuteNonQuery();#endregion                        }dbConn.Close();}}#endregionreturn result;}/// <summary>/// 准备临时表/// </summary>/// <param name="efConnectStr"></param>/// <returns></returns>public DataTable GetTmpNewDataTable(){return this.GetDbHelperSQL_Instance().Query("select * from sc_productsource_temp where 1=2").Tables[0];            }/// <summary>/// 将EF的连接字符串转为Ado.net的连接字符串/// </summary>/// <param name="efConnectStr"></param>/// <returns></returns>private string GetEF_ConnectStr2Ado_ConnectStr(){string[] tmpStr = config.ConnectionStrings.ConnectionStrings["XXX_DBEntities"].ConnectionString.Split(";".ToCharArray());string dbConnStr = string.Empty;if (tmpStr.Length == 8){//拼接出新的可用的ado.net连接字符串dbConnStr = string.Join(";", new string[] { "Data Source =" + base.Connection.DataSource, tmpStr[3], tmpStr[4], tmpStr[5], tmpStr[6].TrimEnd(new char[] { '"' }) });return dbConnStr;}else{return string.Empty;throw new Exception("请配置数据库连接方式为:sql认证方式;不支持WinNT集成安全方式。");}}/// <summary>/// 获取第一行第一列数据/// </summary>/// <param name="efConnectStr"></param>/// <param name="sqlTxt"></param>/// <returns></returns>public string AdoExecuteScalar(string sqlTxt){string dbConnStr = this.GetEF_ConnectStr2Ado_ConnectStr();using (DbHelperSQL db = new DbHelperSQL(dbConnStr)){return db.GetSingle(sqlTxt).ToString();}}public DbHelperSQL GetDbHelperSQL_Instance(){ string dbConnStr = this.GetEF_ConnectStr2Ado_ConnectStr();return new DbHelperSQL(dbConnStr);}}
}

3、修改过的动软DbHelper,Ado.net存储类

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Data.Common;
using System.Collections.Generic;
namespace XXX_App
{/// <summary>/// 数据访问抽象基础类/// Copyright (C) Maticsoft /// </summary>public class DbHelperSQL : IDisposable{//数据库连接字符串(web.config来配置),多数据库可使用DbHelperSQLP来实现.private string connectionString;/// <summary>/// 数据库连接字符串/// </summary>public string ConnectionString{get { return connectionString; }}public DbHelperSQL(string connStr){connectionString = connStr;}#region 公用方法/// <summary>/// 判断是否存在某表的某个字段/// </summary>/// <param name="tableName">表名称</param>/// <param name="columnName">列名称</param>/// <returns>是否存在</returns>public bool ColumnExists(string tableName, string columnName){string sql = "select count(1) from syscolumns where [id]=object_id('" + tableName + "') and [name]='" + columnName + "'";object res = GetSingle(sql);if (res == null){return false;}return Convert.ToInt32(res) > 0;}public int GetMaxID(string FieldName, string TableName){string strsql = "select max(" + FieldName + ")+1 from " + TableName;object obj = GetSingle(strsql);if (obj == null){return 1;}else{return int.Parse(obj.ToString());}}public bool Exists(string strSql){object obj = GetSingle(strSql);int cmdresult;if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){cmdresult = 0;}else{cmdresult = int.Parse(obj.ToString()); //也可能=0}if (cmdresult == 0){return false;}else{return true;}}/// <summary>/// 表是否存在/// </summary>/// <param name="TableName"></param>/// <returns></returns>public bool TabExists(string TableName){string strsql = "select count(*) from sysobjects where id = object_id(N'[" + TableName + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1";//string strsql = "SELECT count(*) FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + TableName + "]') AND type in (N'U')";object obj = GetSingle(strsql);int cmdresult;if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){cmdresult = 0;}else{cmdresult = int.Parse(obj.ToString());}if (cmdresult == 0){return false;}else{return true;}}public bool Exists(string strSql, params SqlParameter[] cmdParms){object obj = GetSingle(strSql, cmdParms);int cmdresult;if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){cmdresult = 0;}else{cmdresult = int.Parse(obj.ToString());}if (cmdresult == 0){return false;}else{return true;}}#endregion#region  执行简单SQL语句/// <summary>/// 执行SQL语句,返回影响的记录数/// </summary>/// <param name="SQLString">SQL语句</param>/// <returns>影响的记录数</returns>public int ExecuteSql(string SQLString){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand(SQLString, connection)){try{connection.Open();int rows = cmd.ExecuteNonQuery();return rows;}catch (System.Data.SqlClient.SqlException e){connection.Close();throw e;}}}}public int ExecuteSqlByTime(string SQLString, int Times){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand(SQLString, connection)){try{connection.Open();cmd.CommandTimeout = Times;int rows = cmd.ExecuteNonQuery();return rows;}catch (System.Data.SqlClient.SqlException e){connection.Close();throw e;}}}}/// <summary>/// 执行多条SQL语句,实现数据库事务。/// </summary>/// <param name="SQLStringList">多条SQL语句</param>      public int ExecuteSqlTran(List<String> SQLStringList){using (SqlConnection conn = new SqlConnection(connectionString)){conn.Open();SqlCommand cmd = new SqlCommand();cmd.Connection = conn;SqlTransaction tx = conn.BeginTransaction();cmd.Transaction = tx;try{int count = 0;for (int n = 0; n < SQLStringList.Count; n++){string strsql = SQLStringList[n];if (strsql.Trim().Length > 1){cmd.CommandText = strsql;count += cmd.ExecuteNonQuery();}}tx.Commit();return count;}catch{tx.Rollback();return 0;}}}/// <summary>/// 执行带一个存储过程参数的的SQL语句。/// </summary>/// <param name="SQLString">SQL语句</param>/// <param name="content">参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加</param>/// <returns>影响的记录数</returns>public int ExecuteSql(string SQLString, string content){using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand cmd = new SqlCommand(SQLString, connection);System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@content", SqlDbType.NText);myParameter.Value = content;cmd.Parameters.Add(myParameter);try{connection.Open();int rows = cmd.ExecuteNonQuery();return rows;}catch (System.Data.SqlClient.SqlException e){throw e;}finally{cmd.Dispose();connection.Close();}}}/// <summary>/// 执行带一个存储过程参数的的SQL语句。/// </summary>/// <param name="SQLString">SQL语句</param>/// <param name="content">参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加</param>/// <returns>影响的记录数</returns>public object ExecuteSqlGet(string SQLString, string content){using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand cmd = new SqlCommand(SQLString, connection);System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@content", SqlDbType.NText);myParameter.Value = content;cmd.Parameters.Add(myParameter);try{connection.Open();object obj = cmd.ExecuteScalar();if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){return null;}else{return obj;}}catch (System.Data.SqlClient.SqlException e){throw e;}finally{cmd.Dispose();connection.Close();}}}/// <summary>/// 向数据库里插入图像格式的字段(和上面情况类似的另一种实例)/// </summary>/// <param name="strSQL">SQL语句</param>/// <param name="fs">图像字节,数据库的字段类型为image的情况</param>/// <returns>影响的记录数</returns>public int ExecuteSqlInsertImg(string strSQL, byte[] fs){using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand cmd = new SqlCommand(strSQL, connection);System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@fs", SqlDbType.Image);myParameter.Value = fs;cmd.Parameters.Add(myParameter);try{connection.Open();int rows = cmd.ExecuteNonQuery();return rows;}catch (System.Data.SqlClient.SqlException e){throw e;}finally{cmd.Dispose();connection.Close();}}}/// <summary>/// 执行一条计算查询结果语句,返回查询结果(object)。/// </summary>/// <param name="SQLString">计算查询结果语句</param>/// <returns>查询结果(object)</returns>public object GetSingle(string SQLString){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand(SQLString, connection)){try{connection.Open();object obj = cmd.ExecuteScalar();if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){return null;}else{return obj;}}catch (System.Data.SqlClient.SqlException e){connection.Close();throw e;}}}}public object GetSingle(string SQLString, int Times){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand(SQLString, connection)){try{connection.Open();cmd.CommandTimeout = Times;object obj = cmd.ExecuteScalar();if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){return null;}else{return obj;}}catch (System.Data.SqlClient.SqlException e){connection.Close();throw e;}}}}/// <summary>/// 执行查询语句,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )/// </summary>/// <param name="strSQL">查询语句</param>/// <returns>SqlDataReader</returns>public SqlDataReader ExecuteReader(string strSQL){SqlConnection connection = new SqlConnection(connectionString);SqlCommand cmd = new SqlCommand(strSQL, connection);try{connection.Open();SqlDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);return myReader;}catch (System.Data.SqlClient.SqlException e){throw e;}}/// <summary>/// 执行查询语句,返回DataSet/// </summary>/// <param name="SQLString">查询语句</param>/// <returns>DataSet</returns>public DataSet Query(string SQLString){using (SqlConnection connection = new SqlConnection(connectionString)){DataSet ds = new DataSet();try{connection.Open();SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);command.Fill(ds, "ds");}catch (System.Data.SqlClient.SqlException ex){throw new Exception(ex.Message);}return ds;}}public DataSet Query(string SQLString, int Times){using (SqlConnection connection = new SqlConnection(connectionString)){DataSet ds = new DataSet();try{connection.Open();SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);command.SelectCommand.CommandTimeout = Times;command.Fill(ds, "ds");}catch (System.Data.SqlClient.SqlException ex){throw new Exception(ex.Message);}return ds;}}#endregion#region 执行带参数的SQL语句/// <summary>/// 执行SQL语句,返回影响的记录数/// </summary>/// <param name="SQLString">SQL语句</param>/// <returns>影响的记录数</returns>public int ExecuteSql(string SQLString, params SqlParameter[] cmdParms){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand()){try{PrepareCommand(cmd, connection, null, SQLString, cmdParms);int rows = cmd.ExecuteNonQuery();cmd.Parameters.Clear();return rows;}catch (System.Data.SqlClient.SqlException e){throw e;}}}}/// <summary>/// 执行多条SQL语句,实现数据库事务。/// </summary>/// <param name="SQLStringList">SQL语句的哈希表(key为sql语句,value是该语句的SqlParameter[])</param>public void ExecuteSqlTran(Hashtable SQLStringList){using (SqlConnection conn = new SqlConnection(connectionString)){conn.Open();using (SqlTransaction trans = conn.BeginTransaction()){SqlCommand cmd = new SqlCommand();try{//循环foreach (DictionaryEntry myDE in SQLStringList){string cmdText = myDE.Key.ToString();SqlParameter[] cmdParms = (SqlParameter[])myDE.Value;PrepareCommand(cmd, conn, trans, cmdText, cmdParms);int val = cmd.ExecuteNonQuery();cmd.Parameters.Clear();}trans.Commit();}catch{trans.Rollback();throw;}}}}/// <summary>/// 执行多条SQL语句,实现数据库事务。/// </summary>/// <param name="SQLStringList">SQL语句的哈希表(key为sql语句,value是该语句的SqlParameter[])</param>public int ExecuteSqlTran(System.Collections.Generic.List<CommandInfo> cmdList){using (SqlConnection conn = new SqlConnection(connectionString)){conn.Open();using (SqlTransaction trans = conn.BeginTransaction()){SqlCommand cmd = new SqlCommand();try{int count = 0;//循环foreach (CommandInfo myDE in cmdList){string cmdText = myDE.CommandText;SqlParameter[] cmdParms = (SqlParameter[])myDE.Parameters;PrepareCommand(cmd, conn, trans, cmdText, cmdParms);if (myDE.EffentNextType == EffentNextType.WhenHaveContine || myDE.EffentNextType == EffentNextType.WhenNoHaveContine){if (myDE.CommandText.ToLower().IndexOf("count(") == -1){trans.Rollback();return 0;}object obj = cmd.ExecuteScalar();bool isHave = false;if (obj == null && obj == DBNull.Value){isHave = false;}isHave = Convert.ToInt32(obj) > 0;if (myDE.EffentNextType == EffentNextType.WhenHaveContine && !isHave){trans.Rollback();return 0;}if (myDE.EffentNextType == EffentNextType.WhenNoHaveContine && isHave){trans.Rollback();return 0;}continue;}int val = cmd.ExecuteNonQuery();count += val;if (myDE.EffentNextType == EffentNextType.ExcuteEffectRows && val == 0){trans.Rollback();return 0;}cmd.Parameters.Clear();}trans.Commit();return count;}catch{trans.Rollback();throw;}}}}/// <summary>/// 执行多条SQL语句,实现数据库事务。/// </summary>/// <param name="SQLStringList">SQL语句的哈希表(key为sql语句,value是该语句的SqlParameter[])</param>public void ExecuteSqlTranWithIndentity(System.Collections.Generic.List<CommandInfo> SQLStringList){using (SqlConnection conn = new SqlConnection(connectionString)){conn.Open();using (SqlTransaction trans = conn.BeginTransaction()){SqlCommand cmd = new SqlCommand();try{int indentity = 0;//循环foreach (CommandInfo myDE in SQLStringList){string cmdText = myDE.CommandText;SqlParameter[] cmdParms = (SqlParameter[])myDE.Parameters;foreach (SqlParameter q in cmdParms){if (q.Direction == ParameterDirection.InputOutput){q.Value = indentity;}}PrepareCommand(cmd, conn, trans, cmdText, cmdParms);int val = cmd.ExecuteNonQuery();foreach (SqlParameter q in cmdParms){if (q.Direction == ParameterDirection.Output){indentity = Convert.ToInt32(q.Value);}}cmd.Parameters.Clear();}trans.Commit();}catch{trans.Rollback();throw;}}}}/// <summary>/// 执行多条SQL语句,实现数据库事务。/// </summary>/// <param name="SQLStringList">SQL语句的哈希表(key为sql语句,value是该语句的SqlParameter[])</param>public void ExecuteSqlTranWithIndentity(Hashtable SQLStringList){using (SqlConnection conn = new SqlConnection(connectionString)){conn.Open();using (SqlTransaction trans = conn.BeginTransaction()){SqlCommand cmd = new SqlCommand();try{int indentity = 0;//循环foreach (DictionaryEntry myDE in SQLStringList){string cmdText = myDE.Key.ToString();SqlParameter[] cmdParms = (SqlParameter[])myDE.Value;foreach (SqlParameter q in cmdParms){if (q.Direction == ParameterDirection.InputOutput){q.Value = indentity;}}PrepareCommand(cmd, conn, trans, cmdText, cmdParms);int val = cmd.ExecuteNonQuery();foreach (SqlParameter q in cmdParms){if (q.Direction == ParameterDirection.Output){indentity = Convert.ToInt32(q.Value);}}cmd.Parameters.Clear();}trans.Commit();}catch{trans.Rollback();throw;}}}}/// <summary>/// 执行一条计算查询结果语句,返回查询结果(object)。/// </summary>/// <param name="SQLString">计算查询结果语句</param>/// <returns>查询结果(object)</returns>public object GetSingle(string SQLString, params SqlParameter[] cmdParms){using (SqlConnection connection = new SqlConnection(connectionString)){using (SqlCommand cmd = new SqlCommand()){try{PrepareCommand(cmd, connection, null, SQLString, cmdParms);object obj = cmd.ExecuteScalar();cmd.Parameters.Clear();if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))){return null;}else{return obj;}}catch (System.Data.SqlClient.SqlException e){throw e;}}}}/// <summary>/// 执行查询语句,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )/// </summary>/// <param name="strSQL">查询语句</param>/// <returns>SqlDataReader</returns>public SqlDataReader ExecuteReader(string SQLString, params SqlParameter[] cmdParms){SqlConnection connection = new SqlConnection(connectionString);SqlCommand cmd = new SqlCommand();try{PrepareCommand(cmd, connection, null, SQLString, cmdParms);SqlDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);cmd.Parameters.Clear();return myReader;}catch (System.Data.SqlClient.SqlException e){throw e;}}/// <summary>/// 执行查询语句,返回DataSet/// </summary>/// <param name="SQLString">查询语句</param>/// <returns>DataSet</returns>public DataSet Query(string SQLString, params SqlParameter[] cmdParms){using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand cmd = new SqlCommand();PrepareCommand(cmd, connection, null, SQLString, cmdParms);using (SqlDataAdapter da = new SqlDataAdapter(cmd)){DataSet ds = new DataSet();try{da.Fill(ds, "ds");cmd.Parameters.Clear();}catch (System.Data.SqlClient.SqlException ex){throw new Exception(ex.Message);}return ds;}}}private void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, string cmdText, SqlParameter[] cmdParms){if (conn.State != ConnectionState.Open)conn.Open();cmd.Connection = conn;cmd.CommandText = cmdText;if (trans != null)cmd.Transaction = trans;cmd.CommandType = CommandType.Text;//cmdType;if (cmdParms != null){foreach (SqlParameter parameter in cmdParms){if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&(parameter.Value == null)){parameter.Value = DBNull.Value;}cmd.Parameters.Add(parameter);}}}#endregion#region 存储过程操作/// <summary>/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )/// </summary>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <returns>SqlDataReader</returns>public SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters){SqlConnection connection = new SqlConnection(connectionString);SqlDataReader returnReader;connection.Open();SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);command.CommandType = CommandType.StoredProcedure;returnReader = command.ExecuteReader(CommandBehavior.CloseConnection);return returnReader;}/// <summary>/// 执行存储过程/// </summary>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <param name="tableName">DataSet结果中的表名</param>/// <returns>DataSet</returns>public DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName){using (SqlConnection connection = new SqlConnection(connectionString)){DataSet dataSet = new DataSet();connection.Open();SqlDataAdapter sqlDA = new SqlDataAdapter();sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);sqlDA.Fill(dataSet, tableName);connection.Close();return dataSet;}}public DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName, int Times){using (SqlConnection connection = new SqlConnection(connectionString)){DataSet dataSet = new DataSet();connection.Open();SqlDataAdapter sqlDA = new SqlDataAdapter();sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);sqlDA.SelectCommand.CommandTimeout = Times;sqlDA.Fill(dataSet, tableName);connection.Close();return dataSet;}}/// <summary>/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)/// </summary>/// <param name="connection">数据库连接</param>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <returns>SqlCommand</returns>private SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters){SqlCommand command = new SqlCommand(storedProcName, connection);command.CommandType = CommandType.StoredProcedure;foreach (SqlParameter parameter in parameters){if (parameter != null){// 检查未分配值的输出参数,将其分配以DBNull.Value.if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&(parameter.Value == null)){parameter.Value = DBNull.Value;}command.Parameters.Add(parameter);}}return command;}/// <summary>/// 执行存储过程,返回影响的行数        /// </summary>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <param name="rowsAffected">影响的行数</param>/// <returns></returns>public int RunProcedure(string storedProcName, IDataParameter[] parameters, out int rowsAffected){using (SqlConnection connection = new SqlConnection(connectionString)){int result;connection.Open();SqlCommand command = BuildIntCommand(connection, storedProcName, parameters);rowsAffected = command.ExecuteNonQuery();result = (int)command.Parameters["ReturnValue"].Value;            return result;}}/// <summary>/// 创建 SqlCommand 对象实例(用来返回一个整数值)   /// </summary>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <returns>SqlCommand 对象实例</returns>private SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters){SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);command.Parameters.Add(new SqlParameter("ReturnValue",SqlDbType.Int, 4, ParameterDirection.ReturnValue,false, 0, 0, string.Empty, DataRowVersion.Default, null));return command;}#endregion#region IDisposable 成员public void Dispose(){connectionString = string.Empty;}#endregion}
}

4、EF的使用和扩展类的使用

/// <summary>/// 解析并入数据库/// </summary>/// <param name="ds"></param>/// <param name="factoryNo"></param>/// <param name="db"></param>public static void XmlFile2DataBase(ref DataSet ds, string factoryNo, XXX_DBEntities db){var dtProductLine = ds.Tables["line"];var dtLinkData = ds.Tables["bc"];//出现过xml缺少字段的情况,84K大小的zip包里的xml bc表只有3个字段,没有批号和日期。如果是这个文件跳过。if (dtLinkData.Columns.Count != 5)return;string outBoxNo = dtLinkData.Rows[0]["out"].ToString();//检测是否有重复记录,有则忽略,该文件只要有一个箱码重复,说明此文件是重复上传。事务控制到文件。decimal cnt = decimal.Parse(db.AdoExecuteScalar(string.Format("select count(*) as cnt from  SC_PRODUCTSOURCE s where s.outbox_dnacode = '{0}'", outBoxNo)).ToString());if (cnt > 0){return;}var dt = db.GetTmpNewDataTable();#region 准备临时数据,并使用OracleBulkCopy批量插入,每产线插一次foreach (DataRow dr in dtProductLine.Rows){if (!string.IsNullOrEmpty(dr["pid"].ToString())){dt.Rows.Clear();int prdCode = int.Parse(dr["psid"].ToString());var product = db.ProductInfo.Where(p => p.PRODUCT_CODE == prdCode).FirstOrDefault();string prdName = product.PRODUCT_CNNAME;string prdBrandName = product.PRD_BRAND;DataView dv = dtLinkData.DefaultView;dv.RowFilter = string.Format("data_Id={0}", dr["line_Id"].ToString());foreach (DataRowView itemRow in dv){string[] itemList = itemRow["bc_Text"].ToString().Split(",".ToCharArray());string batchNo = itemRow["batchno"].ToString();string outBoxNoSub = itemRow["out"].ToString();for (int idx = 0; idx < itemList.Length; idx++){DateTime dtProduct = new DateTime(1901, 01, 01);DateTime.TryParse(itemRow["maketime"].ToString(), out dtProduct);var drProductLinkData = dt.NewRow();#region 一盒的生产数据drProductLinkData["PRODUCTSOURCEID"] = Guid.NewGuid().ToString("N").ToUpper();drProductLinkData["FACTORYID"] = factoryNo;drProductLinkData["PRDLINEID"] = dr["no"].ToString();drProductLinkData["MACRANDOMCODE"] = itemList[idx];drProductLinkData["PRODUCTBATCHIDX"] = batchNo;drProductLinkData["LASERDNA_CODE"] = "";drProductLinkData["PRODUCTNO"] = int.Parse(dr["psid"].ToString());drProductLinkData["PRODUCTNAME"] = prdName;drProductLinkData["PRODUCTTYPENAME"] = prdBrandName;drProductLinkData["PRODUCTDATE"] = dtProduct;drProductLinkData["PRINTCODEDT"] = dtProduct;drProductLinkData["FACTORYSHIFTNO"] = "";drProductLinkData["OUTBOX_DNACODE"] = outBoxNoSub;drProductLinkData["VIRTUALBALECODE"] = "";drProductLinkData["SENDTONDC_DT"] = DateTime.Now;drProductLinkData["FAC_NO"] = factoryNo;drProductLinkData["PRODUCTVERSION"] = DateTime.Now;#endregiondt.Rows.Add(drProductLinkData);}}if (dt.Rows.Count > 0){db.ExecuteSqlBulkCopy(dt);}}}#endregion}

4、程序运行效果及截图

1、日志

2、截图

暂无,因为程序效率太高,一时没有文件需要解析了。呵呵

结束语:做项目不需要定势的思维,比如一定要分层架构,一定要什么牛X的技术,一定要高可扩展性、高可重用性。小项目,快速、稳定、高效和可维护性才是需要考量的要点。天下武功,唯快不破。呵呵...

PS:CSS样式是扒园友的,原来不是在博客设置里写样式,是在页面的HTML模式下加入自定义样式。

entity framework扩展实战,小项目重构,不折腾相关推荐

  1. 【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码

    前言 1.街霸游戏 1.1 KO街霸 程序完整源码 程序的输出界面 1.2 春丽VS巴洛克 参考源码 2.猜谜游戏 2.1简单的猜数字游戏 项目要求 参考源码 2.2 进阶的猜姓名游戏 项目要求 参考 ...

  2. libhv tcp实战小项目

    libhv Tcp小项目实战 一.概述 1.包头 2.心跳 3.任务队列 二.包头 2字节 2字节 4字节 4字节 2字节 1字节 1字节 起始标志 版本号(N) Command(命令ID) 消息体长 ...

  3. 我用Python把抖音上的美女图片转字符画,期望的AI目标更进一步【机器学习算法实战小项目,k聚类算法图片转化字符画】

    大家好,我是辣条. 最近在学习算法,今天给大家带来一个机器学习实战小项目 项目效果展示 学习目标 1.cv2转换图片数据  2.numpy提取图片矩阵数据  3.k均值算法获取图片的分类 工具使用 开 ...

  4. SparkSQL实战小项目之热门商品top3

    SparkSQL实战小项目之热门商品top3 一.说明及需求分析 二.准备测试数据 三.思路分析 四.编码实现 五.验证结果 一.说明及需求分析 软件及环境: centos7 + hive-2.3.3 ...

  5. Vue快速入门(附实战小项目:记事本、天气预报、音乐播放器)

    文章目录 一.前言 二.Vue.js安装 三.初始化Vue项目 四.项目目录解析 五.Vue核心指令 1.插值表达式 2.v-text 3.v-html 4.v-on 5.计数器实战 6.v-show ...

  6. python开发web运维工具_【实战小项目】python开发自动化运维工具--批量操作主机...

    有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子.只不过,很多运维同学学习Python之后,苦于没小项目训练,本篇演示用Python写一个批量操作主机的工具 ...

  7. 100个python进阶实战小项目(适合新手) 微信撤回查看|抖音批量下载等

    Hi~,各位小伙伴,Python是目前编程语言中的主流语言之一,也是公认最容易入门的编程语言,因为Python语言近几年的火爆,有很多小伙伴都开始学习这门语言. 编程语言学习,最重要的是"多 ...

  8. Python实战小项目

    不是很稀饭<复联>嘛,看了<复联4>,就用50行Python代码做了这些: 视频展示:50行代码玩转<复仇者联盟> 教程地址:图片转字符画 相关教程地址:视频转字符 ...

  9. 6个有趣的Python实战小项目,赶紧拿去试试吧

    目录 前言 实战项目一:分析唐诗的作者是李白还是杜甫 实战项目二:自动写检讨书 实战项目三: 屏幕录相机,抓屏软件 实战项目四:听两个聊天机器人互相聊天 实战项目五:彩票随机生成35选7 实战项目六: ...

最新文章

  1. Linux内核学习笔记
  2. 在DWR中实现直接获取一个JAVA类的返回值的两种方法
  3. 网络策略_你知道网络营销策略有哪些吗?
  4. 工作流实战_15_flowable 我发起的流程实例查询
  5. 全国首个凭“码”出行城市,深圳全面实施人员通行认证管理
  6. 白话/图示 sleep_on/wake_up的执行流程
  7. idea 添加格式化json插件GsonFormat 和快速解析第三方返回json数据
  8. VSS 2005 配置(含录像)
  9. AllWinner--R329
  10. 用户故事与敏捷方法—故事不是什么
  11. 台式计算机如何连接投影仪,台式机怎么接投影仪 台式机接投影仪方法【详解】...
  12. MATLAB解微分方程组
  13. sqlite 数据库连接问题以及解决方法
  14. 【react+umi】国际化配置:浏览器默认英文,如何让工程默认语言为中文?
  15. linux 查看非法用户登录,用短信报警来监控linux系统的非法登录用户
  16. python批量放大图片
  17. 现代企业管理笔记——管理理论新进展
  18. 【机试题】2014大疆嵌入式笔试题(附超详细解答,下篇)
  19. css米奇,屹立48年不倒的IP,机械姬为什么能火这么多年?
  20. 10-209 在订单表中查询运费的最大值和最小值

热门文章

  1. 下一个十年,什么样的测试会被大厂争抢?
  2. 做了5年测试连一门语言都没学?逆袭后拿到3个超22K offer!
  3. c++ 文件读写_串行FLASH 文件系统FatFs
  4. android 8.0后台定位,Android 8.0权限说明
  5. java标识符的介绍_Java标识符所有关键字
  6. java 字符串加密解密_Java加密解密字符串
  7. new函数的底层实现
  8. Lesson 3.1 - Python Core Data Types
  9. arm linux 进程页表,arm-linux内存页表创建
  10. 基于Faster R-CNN的安全帽目标检测