.NET+模块编排+数据库操作类的封装+分层架构+实体类+Ajax.net+Athem.NET+javascript+Activex组件+用户权限等

2008.10.13

建了自己的博客后,还没有真正认认真真的写过文章,总是有种感觉思路整理的还是不够清楚,但路总是要走出来的,也希望各位能给与我更多的支持。

最近刚刚完成了一个项目,“基于B/S的资源平台的建设”。

首先介绍一下项目的背景,我们公司是一家专门多媒体教学行业为主的企业,而我所做的资源平台的任务就是将采集下载的视频文件,通过前台网站,供不同用户的用户实现对资源的上传,下载,点播,直播等功能(通过javscript调用Activex组件实现);后台是分为基础管理、资源管理、用户管理、统计分析四个主模块。基础管理分为:公告管理、系统参数、登陆日志、操作日志、友情连接;资源管理分为:资源分类、上传资源、资源添加编辑;用户管理分为:用户添加、编辑、用户权限等;统计分析等分为:资源统计、用户统计等。

以上就是项目的简单背景,下面我将就标题的顺序,介绍这个项目我所用到的架构和技术。

1.模块的编排

当明确了这个项目的需求后,我首先想到的是如何安排工程的模块分布,才能是整个工程整洁有序,为后面的二次开发,提供更好的接口。

整个工程涉及到数据库操作类、Page基类、UserControl基类,实体类、公共类、各个模块的页面、用户控件、以及用到的js、CSS、images等;只有找到合理的模块编排的方式,才能对项目的后期维护和二次开发更为有效,清晰。

首先,将数据库操作类、Page基类、UserControl基类,实体类、公共类放在APP_CODE中,然后建立两个主文件夹,一个放置前台网站模块,另一个放置后提台模块,然后根据设计好的模块分置各个的存储位置,如资源管理主模块,首先在后台模块文件夹下面建立名为“ResManage”文件夹,然后在该文件夹下面建立“Page”、“UserControl”、“images”三个子文件夹,在Page中存放该模块的.aspx页面,UsrControl中存放该模块的.ascx(命名一般根据Page中的.aspx页面),images中存放该模块所用到的图片。

至于一些公共的图片文件夹则直接放置在根目录下。这样整个工程的模块分布就很清晰了。

2.数据库的操作类

数据库的操作类是一个项目的基石,它掌管这我们与数据的直接的数据交互,通过对select、insert、update、delete不同方式的调用,插入,更新等操作采用Hash 算法,实现我们的所需要的功能。

在设计中我们基于SQLHelper框架,可操作Sql Server,Oracle,Access数据库,设计了dbOperate.cs、sqlOperate.cs、OleDbOperate.cs、OraOperate.cs 首先dbOperate.cs是操作的基类,设置数据库连接字符串,数据库类型,对数据的操作等如下:

namespace dbclass

{

//数据库的枚举类型

public enum DbType

{

sqlServer=0,//0

oracle=1, //1

oledb=2

}

public class DbOperate

{

public DbOperate()

{

//

// TODO: 在此处添加构造函数逻辑

//

}

private static DbType _DataBaseType;

private static string _ConnectString = System.Configuration.ConfigurationSettings.AppSettings["con"].ToString();

//数据库类型

public static DbType DataBaseType

{

get

{

return _DataBaseType;

}

set

{

_DataBaseType = value;

}

}

//连接字符串

public static string ConnectString

{

get

{

return _ConnectString;

}

set

{

_ConnectString = value;

}

}

通过在外部设定 DataBaseType,ConnectString属性值,实现对不同数据库的操作和连接字符串的属性。

然后利用重载是实现DataReader,ExecuteNonQuery,DataSet,ExecuteScale等功能,如 ExecuteNonQuery的实现:

public static int ExecuteNonQuery(Hashtable htParams, params string[] commandTexts)

{

int retval = -1;

retval=ExecuteNonQuery(ConnectString, CommandType.Text, GetParameterSet(htParams), commandTexts);

htParams.Clear();

htParams = null;

return retval;

}

public static int ExecuteNonQuery(params string[] commandTexts)

{

return ExecuteNonQuery(ConnectString, CommandType.Text, (IDbDataParameter[])null,commandTexts);

}

public static int ExecuteNonQueryTrans(ArrayList commandTexts)

{

using (IDbConnection con = GetConnection())

{

con.Open();

IDbTransaction trans=con.BeginTransaction();

string strsql="";

IDbCommand cmd = GetCommand();

for(int i=0;i<commandTexts.Count;i++)

{

try

{

strsql = commandTexts[i].ToString();

PrepareCommand(cmd, con, trans, CommandType.Text, strsql, (IDbDataParameter[])null);

cmd.ExecuteNonQuery();

}

catch (Exception e)

{

trans.Rollback();

ShowMessage("数据库执行出错,出错语句:" + strsql + ",出错描述:" + e.Message);

HttpContext.Current.Response.Redirect("~/ErrorPage.aspx?errMessage=" + "数据库操作出错,出错语句:" + strsql + ",出错描述:" + HttpUtility.UrlEncode(e.Message));

break;

}

}

trans.Commit();

}

return 0;

}

public static int ExecuteNonQuery(CommandType commandType, params string[] commandTexts)

{

return ExecuteNonQuery(ConnectString,commandType, (IDbDataParameter[])null,commandTexts);

}

public static int ExecuteNonQuery(string connectionString, CommandType commandType, params string[] commandTexts)

{

return ExecuteNonQuery(connectionString, commandType, (IDbDataParameter [])null,commandTexts);

}

public static int ExecuteNonQuery(string connectionString, CommandType commandType,IDbDataParameter[] commandParameters,params string[] commandTexts)

{

using (IDbConnection cn = GetConnection(connectionString))

{

cn.Open();

return ExecuteNonQuery(cn, commandType, commandParameters,commandTexts);

}

}

public static int ExecuteNonQuery(IDbConnection connection, CommandType commandType, params string[] commandTexts)

{

return ExecuteNonQuery(connection, commandType, (IDbDataParameter[])null,commandTexts);

}

public static int ExecuteNonQuery(IDbConnection connection, CommandType commandType, IDbDataParameter[] commandParameters, params string[] commandTexts)

{

int retval = -1;

try

{

IDbCommand cmd = GetCommand();

PrepareCommand(cmd, connection, (IDbTransaction)null, commandType, GetCommandText(commandTexts), commandParameters);

retval = cmd.ExecuteNonQuery();

cmd.Parameters.Clear();

connection.Close();

}

catch (Exception e)

{

connection.Close();

ShowMessage("数据库操作出错,出错语句:" +GetCommandText(commandTexts) + ",出错描述:" + e.Message);

HttpContext.Current.Trace.Warn("数据库操作出错,出错语句:" + GetCommandText(commandTexts));

HttpContext.Current.Trace.Warn("错误描述信息:" + e.Message);

HttpContext.Current.Response.Redirect("~/ErrorPage.aspx?errMessage=" + "数据库操作出错,出错语句:" + GetCommandText(commandTexts) + ",出错描述:" + HttpUtility.UrlEncode(e.Message));

}

return retval;

}

public static int ExecuteNonQuery(CommandType commandType, string spName, Hashtable paramValue)

{

return ExecuteNonQuery((IDbTransaction)null, commandType, spName, paramValue);

}

public static int ExecuteNonQuery(IDbTransaction transaction, CommandType commandType, string spName, Hashtable paramsValue)

{

int retval = -1;

if ((paramsValue != null) && (paramsValue.Count > 0))

{

IDbDataParameter[] commandParameters =GetSpParameterSet(transaction.Connection.ConnectionString, spName);

AssignParameterValues(commandParameters, paramsValue);

retval = ExecuteNonQuery(transaction, commandType, commandParameters, new string[] { spName});

}

else

{

retval = ExecuteNonQuery(transaction, commandType,(IDbDataParameter[])null, new string[] {spName});

}

paramsValue.Clear();

paramsValue =null;

return retval;

}

public static int ExecuteNonQuery(IDbTransaction transaction, CommandType commandType, params string[] commandTexts)

{

return ExecuteNonQuery(transaction, commandType, (IDbDataParameter[])null,commandTexts);

}

public static int ExecuteNonQuery(IDbTransaction transaction, CommandType commandType, IDbDataParameter[] commandParameters, params string[] commandTexts)

{

int retval = -1;

try

{

IDbCommand cmd = GetCommand();

PrepareCommand(cmd, transaction.Connection, transaction, commandType, GetCommandText(commandTexts), commandParameters);

retval = cmd.ExecuteNonQuery();

cmd.Parameters.Clear();

}

catch (Exception e)

{

transaction.Rollback();

transaction.Connection.Close();

ShowMessage("数据库操作出错,出错语句:" + GetCommandText(commandTexts) + ",出错描述:" + e.Message);

HttpContext.Current.Trace.Warn("数据库操作出错,出错语句:" + GetCommandText(commandTexts));

HttpContext.Current.Trace.Warn("错误描述信息:" + e.Message);

HttpContext.Current.Response.Redirect("~/ErrorPage.aspx?errMessage=" + "数据库操作出错,出错语句:" + GetCommandText(commandTexts) + ",出错描述:" + HttpUtility.UrlEncode(e.Message));

}

return retval;

}

sqlOperate.cs、OleDbOperate.cs、OraOperate.cs提供给接口的特殊功能,如数据的分页,Hash表的实现。下面是sqlOperate.cs的实现。

public static SqlParameter[] GetParameterSet(Hashtable htParams)

{

List<SqlParameter> paramsList = new List<SqlParameter>();

foreach (object key in htParams.Keys)

{

object [] paramAttr=(object [])htParams[key];

SqlParameter param = new SqlParameter();

param.ParameterName = key.ToString();

int precision = 0;

byte scale = 0;

if (paramAttr[1].ToString() != "")

{

string[] sizeAry = paramAttr[1].ToString().Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

precision = int.Parse(sizeAry[0]);

if (sizeAry.Length==2)

{

scale = byte.Parse(sizeAry[1]);

}

}

switch (paramAttr[0].ToString().Trim())

{

case "c":

{

param.SqlDbType = SqlDbType.VarChar;

if (precision != 0)

{

param.Size = precision;

}

break;

}

case "nc":

{

param.SqlDbType = SqlDbType.NVarChar;

if (precision != 0)

{

param.Size = precision;

}

break;

}

case "i":

{

param.SqlDbType = SqlDbType.Int;

break;

}

case "bi":

{

param.SqlDbType = SqlDbType.BigInt;

break;

}

case "dt":

{

param.SqlDbType = SqlDbType.DateTime;

break;

}

case "de":

{

param.SqlDbType = SqlDbType.Decimal;

param.Precision = byte.Parse(precision.ToString());

param.Scale =scale;

break;

}

case "txt":

{

param.SqlDbType = SqlDbType.Text;

break;

}

}

param.Value = paramAttr[2];

paramsList.Add(param);

}

return paramsList.ToArray();

}

//分页读取数据

public static DataTable getPagerData(string strSql, string orderField, string uniqueValueField,int top, int pageSize, int pageIndex,int doCount,out int recordCount)

{

//pageIndex从1开始

//top取记录的数目

recordCount = 0;

string strcmd = "";

string strAfterFrom = strSql.Substring(strSql.IndexOf("from"));//查询字符串中from之后内容

if (doCount != 0)

{

string strAfterFromBeforeOrder = strAfterFrom;

if (strAfterFromBeforeOrder.IndexOf("order") > -1)

{

strAfterFromBeforeOrder = strAfterFromBeforeOrder.Substring(0, strAfterFromBeforeOrder.IndexOf("order"));

}

recordCount= (int)dbclass.DbOperate.ExecuteScalar("select count(*) " + strAfterFromBeforeOrder);

}

if (strSql.IndexOf("order") == -1)

{

if (orderField.Trim() != "")

{

strSql += " order by " + orderField;

strAfterFrom += " order by " + orderField;

}

}

int startRow = (pageIndex - 1) * pageSize + 1;

int endRow = 0;

if (top != 0)

{

endRow = top;

}

else

{

endRow = pageIndex * pageSize;

}

strcmd = "declare @indexTable table(selfid bigint identity(1,1),uniqueValue nvarchar(50));insert into @indexTable(uniqueValue) select top 100 percent " + uniqueValueField + " " + strAfterFrom + ";";

string strAfterSelect = "";//select之后的字符串

strAfterSelect = strSql.Substring(strSql.IndexOf("select") + 6);

strcmd += "select a.* from (select top 100 percent " + strAfterSelect + ") a,@indexTable t where t.uniqueValue=" + uniqueValueField + " and t.selfid>=" + startRow.ToString() + " and t.selfid<=" + endRow.ToString();

DataSet ds;

ds=dbclass.DbOperate.ExecuteDataset(strcmd);

return ds.Tables[0];

}

}

通过先前做的几个项目相比较,现在这个数据库操作基类在这次开发中取得了很好的效果。

今天先发两个部分,后面我将陆续的写出Ajax.net、Athem.NET、javascript结合Activex组件实现多文件,文件夹上传、下载以及视频点播的功能。