工厂模式简单介绍及应用(以数据导入功能实现为例)
2011-03-11 12:06
405 查看
工厂模式:3W
1W:What?
--提供创建对象的接口
2W:Why?
--相当于new创建实例对象,使用该模式,可以让系统具有更好的扩展性/易维护性和复用性,充分展示了面向对象的特点
活字印刷技术就是一个面向对象的应用。 (以下内容属于摘抄)
引:“活字印刷的特点是:第一,要改,只需要更改要改之字,此为可维护;第二,这些字并非用完这次就无用,完全可 以在后来的印刷中重复使用,此乃可复用;第三,若要加字,只需另刻字加入即可,这是可扩展;第四,字的排列可能是竖排可能是横排,此时只需将活字移动就可满足排列需求,此是灵活性好。而在活字印刷术出现之前,上面的四种特性都无法满足。”
3W:How?
--以下介绍一个通过Excel表格向数据库导入数据的功能实现,在下面代码的实现过程就是工厂模式的应用。
-------------------------介绍完毕,进入代码世界-------------------------
第一步:创建前台/后台页面
第二步:创建一个程序集,命名为SXInnerWebPersistent。在该程序集下建立文件夹Model,在该文件夹下创建类文件InputClass.cs
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Collections;using System.Reflection;using System.Data.OleDb;using System.Data.SqlClient;using System.Collections.Generic;using MicrosoftHelper;namespace SXInnerWebPersistent.Model{ /// <summary> /// InputClass 的摘要说明:导入类 /// </summary> public abstract class InputClass { #region 属性 public InputEnty InputCondition = new InputEnty(); private OleDbConnection myConn = null; private DataSet InputDataSet = null; private string[] strSql = null; private string errors = string.Empty; private int ItemCount = 0; //导入项数 protected SqlEnty SqlEnty = new SqlEnty(); protected DataTable FormatTable = null; protected string strTest = string.Empty; protected int successCount = 0; //成功导入个数 protected int fugaiCount = 0; //覆盖导入个数 protected List<StudentEnty> StudentList = new List<StudentEnty>(); #endregion #region 抽象方法 protected abstract void ValidateExcelData(); protected abstract void Insert(); #endregion public InputClass() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 执行导入功能 /// </summary> /// <param name="con"></param> public void ExecuteInput(string con) { try { SqlEnty.ConnStr = con; //数据库连接 myConn = new OleDbConnection(InputCondition.InputConn.ProConn); //Excel数据连接 myConn.Open(); //打开连接 GetDataSource(); if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } ValidateData(); if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } InitObject(); Insert(); } catch { InputCondition.ErrorMsg = "请检查导入模版是否正确"; if (SqlEnty.MyTrans != null && SqlEnty != null) { SqlEnty.MyTrans.Rollback(); } } finally { if (SqlEnty != null && SqlEnty.MyConn != null) { SqlEnty.MyConn.Close(); SqlEnty.MyConn.Dispose(); } } } /// <summary> /// 得到数据源 /// </summary> public void GetDataSource() { if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { System.Data.DataTable ExcelTable = myConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); InputCondition.InputTableNmLst.Add(ExcelTable.Rows[0]["TABLE_NAME"].ToString()); } strSql = new string[2] { "select * from [" + InputCondition.InputTableNmLst[0] + "]", "select {0}, count({0}) as num from [" + InputCondition.InputTableNmLst[0] + "] group by {0}" }; InputDataSet = new DataSet(); OleDbDataAdapter ODDA = new OleDbDataAdapter(strSql[0], myConn); ODDA.Fill(InputDataSet, "table1"); FormatTable = InputDataSet.Tables[0]; //查询Sheet1中的所有数据 ItemCount = FormatTable.Rows.Count; ODDA = new OleDbDataAdapter(string.Format(strSql[1], FormatTable.Columns[0].ColumnName),myConn); ODDA.Fill(InputDataSet, "table2"); myConn.Close(); if (InputDataSet.Tables[0] == null || InputDataSet.Tables[0].Rows.Count.Equals(0)) { InputCondition.ErrorMsg += "所选数据源内没有可导入的数据。<br>"; } } /// <summary> /// 验证数据 /// </summary> public void ValidateData() { #region 判断重复 DataRow[] drs = InputDataSet.Tables[1].Select("num>1"); //以入学编号为主键,查询是否有多个相同入学编号的信息 if (drs != null && !drs.Length.Equals(0)) { errors = "监测站编码为{0}的监测站数据有重复,请检查!<br>" + Environment.NewLine; foreach (DataRow dr in drs) { if (dr[0] != System.DBNull.Value && !String.IsNullOrEmpty(dr[0].ToString())) { InputCondition.ErrorMsg += string.Format(errors, dr[0].ToString()); } } return; } #endregion #region 判断主键是否为空,如果主键为空,则判断主键为空的是否存在记录 for (int i = 0; i < InputDataSet.Tables[1].Rows.Count; i++) { if (string.IsNullOrEmpty(InputDataSet.Tables[1].Rows[i][0].ToString())) { if (InputDataSet.Tables[1].Rows[i]["num"].ToString().Equals("0")) { continue; } InputCondition.ErrorMsg += "文件中存在为空的监测站编码<br>" + Environment.NewLine; break; } } #endregion if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { ValidateExcelData(); } } /// <summary> /// 初始化 /// </summary> private void InitObject() { SqlEnty.MyConn = new SqlConnection(SqlEnty.ConnStr); SqlEnty.MyConn.Open(); SqlEnty.MyTrans = SqlEnty.MyConn.BeginTransaction(); } protected bool isDate(string times) { try { DateTime tm = Convert.ToDateTime(times); return true; } catch { return false; } } } #region 导入实体类 public class InputEnty { private AbstractOledbCommon _InputConn; /// <summary> /// 导入连接 /// </summary> public AbstractOledbCommon InputConn { get { return _InputConn; } set { _InputConn = value; } } private string _SussMsg; /// <summary> /// 导入成功的信息提示 /// </summary> public string SussMsg { get { return _SussMsg; } set { _SussMsg = value; } } private string _ErrorMsg; /// <summary> /// 导入失败的信息提示 /// </summary> public string ErrorMsg { get { return _ErrorMsg; } set { _ErrorMsg = value; } } private bool _isJump = false; /// <summary> /// 是否覆盖存在数据 默认:跳过 /// </summary> public bool IsJump { get { return _isJump; } set { _isJump = value; } } private List<string> _InputTableNmLst = null; public List<string> InputTableNmLst { get { if (_InputTableNmLst == null) { _InputTableNmLst = new List<string>(); } return _InputTableNmLst; } set { _InputTableNmLst = value; } } } #endregion #region Oledb类 public class AbstractOledbCommon { private ProviderType _ProType; /// <summary> /// 类型 /// </summary> public ProviderType ProType { get { return _ProType; } set { _ProType = value; } } private string _ProConn; /// <summary> /// 连接 /// </summary> public string ProConn { get { return _ProConn; } set { _ProConn = value; } } /// <summary> /// 连接模板 /// </summary> public virtual string ProConnTemp { get { return ProConnTemp; } } } #endregion #region 体现继承性 public class ExcelCommon : AbstractOledbCommon { public ExcelCommon() { ProType = ProviderType.Excel; } public override string ProConnTemp { get { return " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source ={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"; } } } public class AccessOledb : AbstractOledbCommon { public AccessOledb() { ProType = ProviderType.Access; } public override string ProConnTemp { get { return " Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}"; } } } public class SqlSvrOledb : AbstractOledbCommon { public SqlSvrOledb() { ProType = ProviderType.SqlSvr; } public override string ProConnTemp { get { return "Provider=SQLOLEDB;Data Source={0};Password={2};User ID={1};Initial Catalog={3}"; } } } #endregion #region 导入类型 public enum ProviderType { Excel = 0, Access = 1, SqlSvr = 2, } #endregion #region 导入工厂 public class InputFactory { public static InputClass CreateObject(string strType) { InputClass IC = null; try { IC = (InputClass)Assembly.Load("SXInnerWebPersistent").CreateInstance("SXInnerWebPersistent.Model." + strType); } catch { } return IC; } } #endregion #region SQL类 public class SqlEnty { private string _ConnStr; /// <summary> /// 数据库连接字符串参数 /// </summary> public string ConnStr { get { return _ConnStr; } set { _ConnStr = value; } } private SqlConnection _MyConn; /// <summary> /// 数据库连接字符串 /// </summary> public SqlConnection MyConn { get { return _MyConn; } set { _MyConn = value; } } private SqlTransaction _MyTrans; /// <summary> /// 数据库事务 /// </summary> public SqlTransaction MyTrans { get { return _MyTrans; } set { _MyTrans = value; } } } #endregion #region 学生访问类 public class StudentInput : InputClass { protected override void ValidateExcelData() { string verror = string.Empty; strTest = "限制长度|SID<5>(学生编码),SNM<8>(学生姓名)//小数带参数|Grade<2-2>(入学成绩)"; MicA.Web.Validate.WebFormValidate wv = new MicA.Web.Validate.WebFormValidate(); IList VErrors = null; // 用来返回检证EXCEL数据的不正确的具体错误 Hashtable t = new Hashtable(); SqlParameter[] pr = new SqlParameter[5]; string[] ItemName = new string[] { "SID", "SNM", "Tm", "Grade", "NT" }; for (int i = 0; i < FormatTable.Rows.Count-1; i++) { for (int j = 0; j < ItemName.Length; j++) { t.Add(ItemName[j].ToString(), FormatTable.Rows[i][j].ToString()); } VErrors = wv.addValidateOnServer(t, strTest); foreach (string ver in VErrors) { verror += ver + " "; } if (!isDate(FormatTable.Rows[i][2].ToString().Trim())) { verror += "入学日期|日期格式不正确,正确的格式信息如 1999-1-1不为空"; } if (string.IsNullOrEmpty(FormatTable.Rows[i][1].ToString())) { InputCondition.ErrorMsg += String.Format("导入第{0}行的姓名必须不为空<br>" + System.Environment.NewLine, (i + 1).ToString()); } if (!string.IsNullOrEmpty(verror)) { InputCondition.ErrorMsg += String.Format("导入第{0}行的数据错误是:{1}<br>" + System.Environment.NewLine, (i + 1).ToString(), verror); } t.Clear(); //移出元素 verror = string.Empty; } } private List<StudentEnty> GetDataList() { List<StudentEnty> objList = new List<StudentEnty>(); string sSql = "SELECT SID,SNM,Tm,Grade,NT from tb_b_StudentInput"; using (SqlDataReader reader = SqlHelper.ExecuteReader(SqlEnty.ConnStr, System.Data.CommandType.Text, sSql)) { while (reader.Read()) { StudentEnty se = new StudentEnty(); _bindInstance(se, reader); objList.Add(se); } } return objList; } /// <summary> /// 实体绑定 /// </summary> /// <param name="obj"></param> /// <param name="data"></param> private static void _bindInstance(StudentEnty obj, IDataReader data) { if (data.IsDBNull(0) == false) { obj.SID = data.GetString(0); } if (data.IsDBNull(1) == false) { obj.SNM = data.GetString(1); } if (data.IsDBNull(2) == false) { obj.Tm = data.GetDateTime(2); } if (data.IsDBNull(3) == false) { obj.Grade = data.GetDecimal(3); } if (data.IsDBNull(4) == false) { obj.NT = data.GetString(4); } } /// <summary> /// 插入数据 /// </summary> protected override void Insert() { if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { ExcelInsert(); } if (fugaiCount != 0) { InputCondition.SussMsg += String.Format("共导入了{0}条数据!覆盖了{1}条数据!", successCount.ToString(), fugaiCount.ToString()); } else { InputCondition.SussMsg += String.Format("共导入了{0}条数据!", successCount.ToString()); } SqlEnty.MyTrans.Commit(); } protected void ExcelInsert() { StudentEnty se = null; for (int i = 0; i < FormatTable.Rows.Count; i++) { if (string.IsNullOrEmpty(FormatTable.Rows[i][0].ToString().Trim())) { continue; } se = new StudentEnty(); _bindInstance2(se, FormatTable.Rows[i]); if (InputCondition.IsJump) { InputCondition.SussMsg += string.Format("导入学生编号为{0}的学生记录时跳过了入学时间为{1}的数据。<br>" + Environment.NewLine, se.SID, se.Tm); continue; } else { try { Delete(se, SqlEnty.MyTrans); } catch { InputCondition.ErrorMsg = "覆盖数据时出现异常"; return; } fugaiCount += 1; } se.SID = FormatTable.Rows[i][0].ToString(); se.SNM = FormatTable.Rows[i][1].ToString(); se.Tm = Convert.ToDateTime(FormatTable.Rows[i][2].ToString()); se.Grade = Convert.ToDecimal(FormatTable.Rows[i][3].ToString()); se.NT = FormatTable.Rows[i][4].ToString(); Insert(se, SqlEnty.MyTrans); successCount += 1; StudentList.Add(se); } } public static void _bindInstance2(StudentEnty obj, DataRow data) { if (data.IsNull(0) == false) { obj.SID = data[0].ToString(); } if (data.IsNull(1) == false) { obj.SNM = data[1].ToString(); } if (data.IsNull(2) == false) { obj.Tm = Convert.ToDateTime(data[2].ToString()); } if (data.IsNull(3) == false) { obj.Grade = Convert.ToDecimal(data[3].ToString()); } if (data.IsNull(4) == false) { obj.NT = data[4].ToString(); } } public void Insert(StudentEnty entity, SqlTransaction sqlst) { string SQL_INSERT = "INSERT INTO tb_b_StudentInput(SID,SNM,Tm,Grade,NT) VALUES(@SID,@SNM,@Tm,@Grade,@NT)"; try { SqlParameter[] paras = getInsertParameters(entity); SqlHelper.ExecuteNonQuery(sqlst, CommandType.Text, SQL_INSERT, paras); } catch (Exception ex) { throw new Exception(ex.Message); } } public void Delete(StudentEnty entity, SqlTransaction sqlst) { string SQL_DELETE = "delete from tb_b_StudentInput where SID in ('" + entity.SID + "') and Tm='" + entity.Tm + "'"; try { SqlHelper.ExecuteNonQuery(sqlst, CommandType.Text, SQL_DELETE); } catch (Exception exx) { throw new Exception(exx.Message); } } public static SqlParameter[] getInsertParameters(StudentEnty obj) { SqlParameter op1 = new SqlParameter("@SID", SqlDbType.Char); op1.Value = obj.SID; SqlParameter op2 = new SqlParameter("@SNM", SqlDbType.Char); op2.Value = obj.SNM; SqlParameter op3 = new SqlParameter("@Tm", SqlDbType.DateTime); op3.Value = obj.Tm; SqlParameter op4 = new SqlParameter("@Grade", SqlDbType.Decimal); op4.Value = obj.Grade; SqlParameter op5 = new SqlParameter("@NT", SqlDbType.Char); op5.Value = obj.NT; return new SqlParameter[] { op1, op2, op3, op4, op5 }; } } #endregion #region 学生实体类 public class StudentEnty { private string _SID; /// <summary> /// 学生编号 /// </summary> public string SID { get { return _SID; } set { _SID = value; } } private string _SNM; /// <summary> /// 学生姓名 /// </summary> public string SNM { get { return _SNM; } set { _SNM = value; } } private DateTime _Tm; /// <summary> /// 入学日期 /// </summary> public DateTime Tm { get { return _Tm; } set { _Tm = value; } } private decimal _Grade; /// <summary> /// 入学成绩 /// </summary> public decimal Grade { get { return _Grade; } set { _Grade = value; } } private string _NT; /// <summary> /// 备注 /// </summary> public string NT { get { return _NT; } set { _NT = value; } } } #endregion}
注意:在使用Assembly.Load(程序集名称).CreateInstance(命名空间+类名)有可能会出现错误或是null值
出现这类问题的原因与解决方法是:
1.请检查数据层是否实现了接口
dll下面的具体类是否实现了接口的定义
2.请检查程序集名称和命名空间不一致
Assembly.Load(path)这里的path必须是一个程序集的名称,而不是类命名空间的名称。
CreateInstance(CacheKey)这里的CacheKey其实是需要反射的类型全名(程序集名称+类名)
3.请检查BLL层是否添加了该项目引用
1W:What?
--提供创建对象的接口
2W:Why?
--相当于new创建实例对象,使用该模式,可以让系统具有更好的扩展性/易维护性和复用性,充分展示了面向对象的特点
活字印刷技术就是一个面向对象的应用。 (以下内容属于摘抄)
引:“活字印刷的特点是:第一,要改,只需要更改要改之字,此为可维护;第二,这些字并非用完这次就无用,完全可 以在后来的印刷中重复使用,此乃可复用;第三,若要加字,只需另刻字加入即可,这是可扩展;第四,字的排列可能是竖排可能是横排,此时只需将活字移动就可满足排列需求,此是灵活性好。而在活字印刷术出现之前,上面的四种特性都无法满足。”
3W:How?
--以下介绍一个通过Excel表格向数据库导入数据的功能实现,在下面代码的实现过程就是工厂模式的应用。
-------------------------介绍完毕,进入代码世界-------------------------
第一步:创建前台/后台页面
using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.IO;using SXInnerWebPersistent.Model;public partial class 导入数据_导入 : BasePage{ #region 属性设置 private string TempUrl = "../Template/StudentInput.xls"; //模板路径 private string errorMsg = string.Empty; //上传保存时的错误消息 private string FileName = string.Empty; //上传文件名称 #endregion protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { isExt(TempUrl); //判断模板是否存在 } btnOk.ImageUrl = "../Images/qd5.jpg"; } /// <summary> /// 判断模板是否存在:1存在 0不存在 /// </summary> /// <param name="url">模板路径</param> private void isExt(string url) { try { if (File.Exists(Server.MapPath(url))) { txtIsExist.Value = "1"; txtTempUrl.Value = url; } else { txtIsExist.Value = "0"; } } catch (Exception ex) { Console.Write(ex.Message); txtIsExist.Value = "0"; } } protected void btnOk_Click(object sender, ImageClickEventArgs e) { try { VolidateFile(ref errorMsg); //调用一 if (!string.IsNullOrEmpty(errorMsg)) { tblInfo.Rows[0].Cells[0].InnerHtml = errorMsg; return; } UpLoadFile(ref FileName); //调用二 AbstractOledbCommon AOC = new ExcelCommon(); AOC.ProConn = string.Format(AOC.ProConnTemp, FileName); InputEnty enty = new InputEnty(); enty.IsJump = rbJump.Checked; enty.InputConn = AOC; InputClass myInput = InputFactory.CreateObject("StudentInput"); myInput.InputCondition = enty; myInput.ExecuteInput(this.connStr); tblInfo.Rows[0].Cells[0].InnerHtml = myInput.InputCondition.SussMsg + myInput.InputCondition.ErrorMsg; string tmp = "<mce:script language=/"javascript/"><!--proBar.runtimeStyle.visibility=/"hidden/";// --></mce:script>"; if (!IsStartupScriptRegistered("re")) RegisterStartupScript("re", tmp); } catch { tblInfo.Rows[0].Cells[0].InnerHtml = "导入失败!请检查导入文件"; } } /// <summary> /// 验证文件 /// </summary> /// <param name="errorMsg">错误消息</param> private void VolidateFile(ref string errorMsg) { if (!string.IsNullOrEmpty(this.File1.PostedFile.FileName.Trim())) //判断上传文件是否存在 { if (this.File1.PostedFile.FileName.Substring(this.File1.PostedFile.FileName.LastIndexOf('.') + 1).Equals("xls")) //判断上传文件格式 { if (this.File1.PostedFile.ContentLength > 10485670) //判断上传文件是否容量过大 { errorMsg = "文件过大!请分几次导入!"; } } else { errorMsg = "导入的文件格式不对,请选择excel文件!"; } } else { errorMsg = "不能上传空文件"; } } /// <summary> /// 上传文件 /// </summary> private void UpLoadFile(ref string fileName) { fileName = Request.PhysicalApplicationPath + @"TempFile/"; //路径 fileName = fileName + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xls"; //保存名称 File1.PostedFile.SaveAs(fileName); /*** 这是我注意不到的地方 ***/ File1.Dispose(); //释放资源 GC.Collect(); //垃圾回收 }}
第二步:创建一个程序集,命名为SXInnerWebPersistent。在该程序集下建立文件夹Model,在该文件夹下创建类文件InputClass.cs
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Collections;using System.Reflection;using System.Data.OleDb;using System.Data.SqlClient;using System.Collections.Generic;using MicrosoftHelper;namespace SXInnerWebPersistent.Model{ /// <summary> /// InputClass 的摘要说明:导入类 /// </summary> public abstract class InputClass { #region 属性 public InputEnty InputCondition = new InputEnty(); private OleDbConnection myConn = null; private DataSet InputDataSet = null; private string[] strSql = null; private string errors = string.Empty; private int ItemCount = 0; //导入项数 protected SqlEnty SqlEnty = new SqlEnty(); protected DataTable FormatTable = null; protected string strTest = string.Empty; protected int successCount = 0; //成功导入个数 protected int fugaiCount = 0; //覆盖导入个数 protected List<StudentEnty> StudentList = new List<StudentEnty>(); #endregion #region 抽象方法 protected abstract void ValidateExcelData(); protected abstract void Insert(); #endregion public InputClass() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 执行导入功能 /// </summary> /// <param name="con"></param> public void ExecuteInput(string con) { try { SqlEnty.ConnStr = con; //数据库连接 myConn = new OleDbConnection(InputCondition.InputConn.ProConn); //Excel数据连接 myConn.Open(); //打开连接 GetDataSource(); if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } ValidateData(); if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } InitObject(); Insert(); } catch { InputCondition.ErrorMsg = "请检查导入模版是否正确"; if (SqlEnty.MyTrans != null && SqlEnty != null) { SqlEnty.MyTrans.Rollback(); } } finally { if (SqlEnty != null && SqlEnty.MyConn != null) { SqlEnty.MyConn.Close(); SqlEnty.MyConn.Dispose(); } } } /// <summary> /// 得到数据源 /// </summary> public void GetDataSource() { if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { System.Data.DataTable ExcelTable = myConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); InputCondition.InputTableNmLst.Add(ExcelTable.Rows[0]["TABLE_NAME"].ToString()); } strSql = new string[2] { "select * from [" + InputCondition.InputTableNmLst[0] + "]", "select {0}, count({0}) as num from [" + InputCondition.InputTableNmLst[0] + "] group by {0}" }; InputDataSet = new DataSet(); OleDbDataAdapter ODDA = new OleDbDataAdapter(strSql[0], myConn); ODDA.Fill(InputDataSet, "table1"); FormatTable = InputDataSet.Tables[0]; //查询Sheet1中的所有数据 ItemCount = FormatTable.Rows.Count; ODDA = new OleDbDataAdapter(string.Format(strSql[1], FormatTable.Columns[0].ColumnName),myConn); ODDA.Fill(InputDataSet, "table2"); myConn.Close(); if (InputDataSet.Tables[0] == null || InputDataSet.Tables[0].Rows.Count.Equals(0)) { InputCondition.ErrorMsg += "所选数据源内没有可导入的数据。<br>"; } } /// <summary> /// 验证数据 /// </summary> public void ValidateData() { #region 判断重复 DataRow[] drs = InputDataSet.Tables[1].Select("num>1"); //以入学编号为主键,查询是否有多个相同入学编号的信息 if (drs != null && !drs.Length.Equals(0)) { errors = "监测站编码为{0}的监测站数据有重复,请检查!<br>" + Environment.NewLine; foreach (DataRow dr in drs) { if (dr[0] != System.DBNull.Value && !String.IsNullOrEmpty(dr[0].ToString())) { InputCondition.ErrorMsg += string.Format(errors, dr[0].ToString()); } } return; } #endregion #region 判断主键是否为空,如果主键为空,则判断主键为空的是否存在记录 for (int i = 0; i < InputDataSet.Tables[1].Rows.Count; i++) { if (string.IsNullOrEmpty(InputDataSet.Tables[1].Rows[i][0].ToString())) { if (InputDataSet.Tables[1].Rows[i]["num"].ToString().Equals("0")) { continue; } InputCondition.ErrorMsg += "文件中存在为空的监测站编码<br>" + Environment.NewLine; break; } } #endregion if (!string.IsNullOrEmpty(InputCondition.ErrorMsg)) { return; } if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { ValidateExcelData(); } } /// <summary> /// 初始化 /// </summary> private void InitObject() { SqlEnty.MyConn = new SqlConnection(SqlEnty.ConnStr); SqlEnty.MyConn.Open(); SqlEnty.MyTrans = SqlEnty.MyConn.BeginTransaction(); } protected bool isDate(string times) { try { DateTime tm = Convert.ToDateTime(times); return true; } catch { return false; } } } #region 导入实体类 public class InputEnty { private AbstractOledbCommon _InputConn; /// <summary> /// 导入连接 /// </summary> public AbstractOledbCommon InputConn { get { return _InputConn; } set { _InputConn = value; } } private string _SussMsg; /// <summary> /// 导入成功的信息提示 /// </summary> public string SussMsg { get { return _SussMsg; } set { _SussMsg = value; } } private string _ErrorMsg; /// <summary> /// 导入失败的信息提示 /// </summary> public string ErrorMsg { get { return _ErrorMsg; } set { _ErrorMsg = value; } } private bool _isJump = false; /// <summary> /// 是否覆盖存在数据 默认:跳过 /// </summary> public bool IsJump { get { return _isJump; } set { _isJump = value; } } private List<string> _InputTableNmLst = null; public List<string> InputTableNmLst { get { if (_InputTableNmLst == null) { _InputTableNmLst = new List<string>(); } return _InputTableNmLst; } set { _InputTableNmLst = value; } } } #endregion #region Oledb类 public class AbstractOledbCommon { private ProviderType _ProType; /// <summary> /// 类型 /// </summary> public ProviderType ProType { get { return _ProType; } set { _ProType = value; } } private string _ProConn; /// <summary> /// 连接 /// </summary> public string ProConn { get { return _ProConn; } set { _ProConn = value; } } /// <summary> /// 连接模板 /// </summary> public virtual string ProConnTemp { get { return ProConnTemp; } } } #endregion #region 体现继承性 public class ExcelCommon : AbstractOledbCommon { public ExcelCommon() { ProType = ProviderType.Excel; } public override string ProConnTemp { get { return " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source ={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"; } } } public class AccessOledb : AbstractOledbCommon { public AccessOledb() { ProType = ProviderType.Access; } public override string ProConnTemp { get { return " Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}"; } } } public class SqlSvrOledb : AbstractOledbCommon { public SqlSvrOledb() { ProType = ProviderType.SqlSvr; } public override string ProConnTemp { get { return "Provider=SQLOLEDB;Data Source={0};Password={2};User ID={1};Initial Catalog={3}"; } } } #endregion #region 导入类型 public enum ProviderType { Excel = 0, Access = 1, SqlSvr = 2, } #endregion #region 导入工厂 public class InputFactory { public static InputClass CreateObject(string strType) { InputClass IC = null; try { IC = (InputClass)Assembly.Load("SXInnerWebPersistent").CreateInstance("SXInnerWebPersistent.Model." + strType); } catch { } return IC; } } #endregion #region SQL类 public class SqlEnty { private string _ConnStr; /// <summary> /// 数据库连接字符串参数 /// </summary> public string ConnStr { get { return _ConnStr; } set { _ConnStr = value; } } private SqlConnection _MyConn; /// <summary> /// 数据库连接字符串 /// </summary> public SqlConnection MyConn { get { return _MyConn; } set { _MyConn = value; } } private SqlTransaction _MyTrans; /// <summary> /// 数据库事务 /// </summary> public SqlTransaction MyTrans { get { return _MyTrans; } set { _MyTrans = value; } } } #endregion #region 学生访问类 public class StudentInput : InputClass { protected override void ValidateExcelData() { string verror = string.Empty; strTest = "限制长度|SID<5>(学生编码),SNM<8>(学生姓名)//小数带参数|Grade<2-2>(入学成绩)"; MicA.Web.Validate.WebFormValidate wv = new MicA.Web.Validate.WebFormValidate(); IList VErrors = null; // 用来返回检证EXCEL数据的不正确的具体错误 Hashtable t = new Hashtable(); SqlParameter[] pr = new SqlParameter[5]; string[] ItemName = new string[] { "SID", "SNM", "Tm", "Grade", "NT" }; for (int i = 0; i < FormatTable.Rows.Count-1; i++) { for (int j = 0; j < ItemName.Length; j++) { t.Add(ItemName[j].ToString(), FormatTable.Rows[i][j].ToString()); } VErrors = wv.addValidateOnServer(t, strTest); foreach (string ver in VErrors) { verror += ver + " "; } if (!isDate(FormatTable.Rows[i][2].ToString().Trim())) { verror += "入学日期|日期格式不正确,正确的格式信息如 1999-1-1不为空"; } if (string.IsNullOrEmpty(FormatTable.Rows[i][1].ToString())) { InputCondition.ErrorMsg += String.Format("导入第{0}行的姓名必须不为空<br>" + System.Environment.NewLine, (i + 1).ToString()); } if (!string.IsNullOrEmpty(verror)) { InputCondition.ErrorMsg += String.Format("导入第{0}行的数据错误是:{1}<br>" + System.Environment.NewLine, (i + 1).ToString(), verror); } t.Clear(); //移出元素 verror = string.Empty; } } private List<StudentEnty> GetDataList() { List<StudentEnty> objList = new List<StudentEnty>(); string sSql = "SELECT SID,SNM,Tm,Grade,NT from tb_b_StudentInput"; using (SqlDataReader reader = SqlHelper.ExecuteReader(SqlEnty.ConnStr, System.Data.CommandType.Text, sSql)) { while (reader.Read()) { StudentEnty se = new StudentEnty(); _bindInstance(se, reader); objList.Add(se); } } return objList; } /// <summary> /// 实体绑定 /// </summary> /// <param name="obj"></param> /// <param name="data"></param> private static void _bindInstance(StudentEnty obj, IDataReader data) { if (data.IsDBNull(0) == false) { obj.SID = data.GetString(0); } if (data.IsDBNull(1) == false) { obj.SNM = data.GetString(1); } if (data.IsDBNull(2) == false) { obj.Tm = data.GetDateTime(2); } if (data.IsDBNull(3) == false) { obj.Grade = data.GetDecimal(3); } if (data.IsDBNull(4) == false) { obj.NT = data.GetString(4); } } /// <summary> /// 插入数据 /// </summary> protected override void Insert() { if (InputCondition.InputConn.ProType.Equals(ProviderType.Excel)) { ExcelInsert(); } if (fugaiCount != 0) { InputCondition.SussMsg += String.Format("共导入了{0}条数据!覆盖了{1}条数据!", successCount.ToString(), fugaiCount.ToString()); } else { InputCondition.SussMsg += String.Format("共导入了{0}条数据!", successCount.ToString()); } SqlEnty.MyTrans.Commit(); } protected void ExcelInsert() { StudentEnty se = null; for (int i = 0; i < FormatTable.Rows.Count; i++) { if (string.IsNullOrEmpty(FormatTable.Rows[i][0].ToString().Trim())) { continue; } se = new StudentEnty(); _bindInstance2(se, FormatTable.Rows[i]); if (InputCondition.IsJump) { InputCondition.SussMsg += string.Format("导入学生编号为{0}的学生记录时跳过了入学时间为{1}的数据。<br>" + Environment.NewLine, se.SID, se.Tm); continue; } else { try { Delete(se, SqlEnty.MyTrans); } catch { InputCondition.ErrorMsg = "覆盖数据时出现异常"; return; } fugaiCount += 1; } se.SID = FormatTable.Rows[i][0].ToString(); se.SNM = FormatTable.Rows[i][1].ToString(); se.Tm = Convert.ToDateTime(FormatTable.Rows[i][2].ToString()); se.Grade = Convert.ToDecimal(FormatTable.Rows[i][3].ToString()); se.NT = FormatTable.Rows[i][4].ToString(); Insert(se, SqlEnty.MyTrans); successCount += 1; StudentList.Add(se); } } public static void _bindInstance2(StudentEnty obj, DataRow data) { if (data.IsNull(0) == false) { obj.SID = data[0].ToString(); } if (data.IsNull(1) == false) { obj.SNM = data[1].ToString(); } if (data.IsNull(2) == false) { obj.Tm = Convert.ToDateTime(data[2].ToString()); } if (data.IsNull(3) == false) { obj.Grade = Convert.ToDecimal(data[3].ToString()); } if (data.IsNull(4) == false) { obj.NT = data[4].ToString(); } } public void Insert(StudentEnty entity, SqlTransaction sqlst) { string SQL_INSERT = "INSERT INTO tb_b_StudentInput(SID,SNM,Tm,Grade,NT) VALUES(@SID,@SNM,@Tm,@Grade,@NT)"; try { SqlParameter[] paras = getInsertParameters(entity); SqlHelper.ExecuteNonQuery(sqlst, CommandType.Text, SQL_INSERT, paras); } catch (Exception ex) { throw new Exception(ex.Message); } } public void Delete(StudentEnty entity, SqlTransaction sqlst) { string SQL_DELETE = "delete from tb_b_StudentInput where SID in ('" + entity.SID + "') and Tm='" + entity.Tm + "'"; try { SqlHelper.ExecuteNonQuery(sqlst, CommandType.Text, SQL_DELETE); } catch (Exception exx) { throw new Exception(exx.Message); } } public static SqlParameter[] getInsertParameters(StudentEnty obj) { SqlParameter op1 = new SqlParameter("@SID", SqlDbType.Char); op1.Value = obj.SID; SqlParameter op2 = new SqlParameter("@SNM", SqlDbType.Char); op2.Value = obj.SNM; SqlParameter op3 = new SqlParameter("@Tm", SqlDbType.DateTime); op3.Value = obj.Tm; SqlParameter op4 = new SqlParameter("@Grade", SqlDbType.Decimal); op4.Value = obj.Grade; SqlParameter op5 = new SqlParameter("@NT", SqlDbType.Char); op5.Value = obj.NT; return new SqlParameter[] { op1, op2, op3, op4, op5 }; } } #endregion #region 学生实体类 public class StudentEnty { private string _SID; /// <summary> /// 学生编号 /// </summary> public string SID { get { return _SID; } set { _SID = value; } } private string _SNM; /// <summary> /// 学生姓名 /// </summary> public string SNM { get { return _SNM; } set { _SNM = value; } } private DateTime _Tm; /// <summary> /// 入学日期 /// </summary> public DateTime Tm { get { return _Tm; } set { _Tm = value; } } private decimal _Grade; /// <summary> /// 入学成绩 /// </summary> public decimal Grade { get { return _Grade; } set { _Grade = value; } } private string _NT; /// <summary> /// 备注 /// </summary> public string NT { get { return _NT; } set { _NT = value; } } } #endregion}
注意:在使用Assembly.Load(程序集名称).CreateInstance(命名空间+类名)有可能会出现错误或是null值
出现这类问题的原因与解决方法是:
1.请检查数据层是否实现了接口
dll下面的具体类是否实现了接口的定义
2.请检查程序集名称和命名空间不一致
Assembly.Load(path)这里的path必须是一个程序集的名称,而不是类命名空间的名称。
CreateInstance(CacheKey)这里的CacheKey其实是需要反射的类型全名(程序集名称+类名)
3.请检查BLL层是否添加了该项目引用
相关文章推荐
- EXTJS学习系列提高篇:第二篇(转载)作者殷良胜,结合EXT2.2+C#.net实现将数据导入Excel的功能
- 用最简单的函数实现功能:判断一个int数据是否是2的x次幂(不能使用循环)。
- 微信小程序简单实现form表单获取输入数据功能示例
- SQL Server简单实现数据的日报和月报功能
- GeneXus中的grid数据导入至Excel中和Excel中数据导入至grid中的简单代码实现
- C# 将Excel数据导入到数据库(实现SQL2000企业管理器导入EXCEL功能)
- 使用Java实现简单的server/client回显功能的方法介绍
- ODPS功能介绍之数据导入
- 一起来单页应用吧,实现简单微博功能!(下)
- SQL本地分布式操作远程数据库,可用于实现导入,导出等数据操作功能
- JDBC+Servlet+JSP实现简单的数据遍历和查找功能
- Android5.1.1实现备份应用数据功能
- 模块管理常规功能自定义系统的设计与实现(10--数据新增[三、批量导入数据])
- 实现一个简单的摄像功能(不带传输数据)代码片段
- 【小试身手】几个自定义控件的组合应用,实现简单的“增删改查”功能(有源码)
- Session对象的应用:实现简单的购物车的功能
- c#直接调用ssis包实现Sql Server的数据导入功能
- Android广播事件机制及应用(实现简单的定时提醒功能)
- 如何在应用系统中实现数据权限的控制功能(2)
- 使用Java实现简单的server/client回显功能的方法介绍