entity framework扩展实战,小项目重构,不折腾
一个控制台程序,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扩展实战,小项目重构,不折腾相关推荐
- 【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码
前言 1.街霸游戏 1.1 KO街霸 程序完整源码 程序的输出界面 1.2 春丽VS巴洛克 参考源码 2.猜谜游戏 2.1简单的猜数字游戏 项目要求 参考源码 2.2 进阶的猜姓名游戏 项目要求 参考 ...
- libhv tcp实战小项目
libhv Tcp小项目实战 一.概述 1.包头 2.心跳 3.任务队列 二.包头 2字节 2字节 4字节 4字节 2字节 1字节 1字节 起始标志 版本号(N) Command(命令ID) 消息体长 ...
- 我用Python把抖音上的美女图片转字符画,期望的AI目标更进一步【机器学习算法实战小项目,k聚类算法图片转化字符画】
大家好,我是辣条. 最近在学习算法,今天给大家带来一个机器学习实战小项目 项目效果展示 学习目标 1.cv2转换图片数据 2.numpy提取图片矩阵数据 3.k均值算法获取图片的分类 工具使用 开 ...
- SparkSQL实战小项目之热门商品top3
SparkSQL实战小项目之热门商品top3 一.说明及需求分析 二.准备测试数据 三.思路分析 四.编码实现 五.验证结果 一.说明及需求分析 软件及环境: centos7 + hive-2.3.3 ...
- Vue快速入门(附实战小项目:记事本、天气预报、音乐播放器)
文章目录 一.前言 二.Vue.js安装 三.初始化Vue项目 四.项目目录解析 五.Vue核心指令 1.插值表达式 2.v-text 3.v-html 4.v-on 5.计数器实战 6.v-show ...
- python开发web运维工具_【实战小项目】python开发自动化运维工具--批量操作主机...
有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子.只不过,很多运维同学学习Python之后,苦于没小项目训练,本篇演示用Python写一个批量操作主机的工具 ...
- 100个python进阶实战小项目(适合新手) 微信撤回查看|抖音批量下载等
Hi~,各位小伙伴,Python是目前编程语言中的主流语言之一,也是公认最容易入门的编程语言,因为Python语言近几年的火爆,有很多小伙伴都开始学习这门语言. 编程语言学习,最重要的是"多 ...
- Python实战小项目
不是很稀饭<复联>嘛,看了<复联4>,就用50行Python代码做了这些: 视频展示:50行代码玩转<复仇者联盟> 教程地址:图片转字符画 相关教程地址:视频转字符 ...
- 6个有趣的Python实战小项目,赶紧拿去试试吧
目录 前言 实战项目一:分析唐诗的作者是李白还是杜甫 实战项目二:自动写检讨书 实战项目三: 屏幕录相机,抓屏软件 实战项目四:听两个聊天机器人互相聊天 实战项目五:彩票随机生成35选7 实战项目六: ...
最新文章
- Linux内核学习笔记
- 在DWR中实现直接获取一个JAVA类的返回值的两种方法
- 网络策略_你知道网络营销策略有哪些吗?
- 工作流实战_15_flowable 我发起的流程实例查询
- 全国首个凭“码”出行城市,深圳全面实施人员通行认证管理
- 白话/图示 sleep_on/wake_up的执行流程
- idea 添加格式化json插件GsonFormat 和快速解析第三方返回json数据
- VSS 2005 配置(含录像)
- AllWinner--R329
- 用户故事与敏捷方法—故事不是什么
- 台式计算机如何连接投影仪,台式机怎么接投影仪 台式机接投影仪方法【详解】...
- MATLAB解微分方程组
- sqlite 数据库连接问题以及解决方法
- 【react+umi】国际化配置:浏览器默认英文,如何让工程默认语言为中文?
- linux 查看非法用户登录,用短信报警来监控linux系统的非法登录用户
- python批量放大图片
- 现代企业管理笔记——管理理论新进展
- 【机试题】2014大疆嵌入式笔试题(附超详细解答,下篇)
- css米奇,屹立48年不倒的IP,机械姬为什么能火这么多年?
- 10-209 在订单表中查询运费的最大值和最小值
热门文章
- 下一个十年,什么样的测试会被大厂争抢?
- 做了5年测试连一门语言都没学?逆袭后拿到3个超22K offer!
- c++ 文件读写_串行FLASH 文件系统FatFs
- android 8.0后台定位,Android 8.0权限说明
- java标识符的介绍_Java标识符所有关键字
- java 字符串加密解密_Java加密解密字符串
- new函数的底层实现
- Lesson 3.1 - Python Core Data Types
- arm linux 进程页表,arm-linux内存页表创建
- 基于Faster R-CNN的安全帽目标检测