Asp.Net(C#)+Sql Server三层架构下数据存取方案

Asp.Net(C#)+Sql Server三层架构下数据存取方案

引言:

参与了一个大型社区程序的开发,现在将相关开发经验陆续总结出来,和大家探讨一下。本节主要想与大家探讨一种数据读取方案:集合类代替直接从数据库中获取的DataSet,主要好处就是可以解决Sql Server吞吐量的瓶颈问题。一般小数量的程序不会有问题,但数据以十万百万条计的时候,数据库的吞吐量的限制就会表现的比较明显。这里的解决方案其实也就是把海量数据信息分成一条条取出,以频繁取库的代价解决瓶颈限制,其实也就是把数据库服务器的负担让WEB服务器分担了。闲话少说,进入正题, 们的例子还是社区程序中的一个配置表的读取, 们就是要 据一定条件来从数据库中获取数据。

一、数据库设计:

 

ScoreSetting   积分设置表

Key:   ScoreSettingID

Field name

Type

Length

Default

Description

ScoreSettingID

int

4

0

ScoreSettingID(自动编号)

FunctionID

int

4

0

 功能ID

OperationID

int

4

0

 操作ID

RoleTypeID

int

4

0

 身份ID

BBSTypeID

int

4

0

 论坛类别ID

Score

int

4

0

 积分数

BB

int

4

0

 币币数

BuyType

Int

4

0

  购买类型

FunctionState

int

4

0

 0:否,1:是,2:购买


存储过程:

/**********************************

功能: 据一定条件读取功能记录

作者:Rexsp

创建日期:2004-01-13

修改者:

修改日期:

**********************************/

ALTER PROCEDURE GetScoreSetting

(  

    @ScoreSettingID INT=-1,                    ---设置ID

     @FunctionID INT=-1,                        ---功能ID

     @OperationID INT=-1,                       ---操作ID

     @RoleTypeID INT=-1,                        ---角色类型

     @BBSTypeID INT=-1,                         ---版块类型

     @Score INT=-1,                             ---积分设置  

     @BB INT=-1,                                ---币币设置

     @BuyType INT=-1,                           ---购买类型 0:不是购买类型 1:一次性购买 2:反复购买

     @FunctionState INT=-1                      ---功能状态

)

AS

SET NOCOUNT ON

DECLARE @strSQL NVARCHAR(1000)

SET @strSQL = 'SELECT * FROM [ScoreSetting] WHERE @ckScoreSettingID = @ckScoreSettingID'

--- Add KeyWords Begin ---

IF @ScoreSettingID<> -1

     BEGIN

         SET @strSQL = @strSQL + ' AND ScoreSettingID= @ckScoreSettingID'

     END

IF @FunctionID<> -1

     BEGIN

         SET @strSQL = @strSQL + ' AND FunctionID= @ckFunctionID'

     END

IF @OperationID<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND OperationID = @ckOperationID'

     END

IF @RoleTypeID<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  RoleTypeID = @ckRoleTypeID'

     END

IF @BBSTypeID<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  BBSTypeID = @ckBBSTypeID'

     END

IF @Score<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  Score = @ckScore'

     END

IF @BB<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  BB= @ckBB'

     END

IF @BuyType<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  BuyType= @ckBuyType'

     END

IF @FunctionState<>-1

     BEGIN

         SET @strSQL = @strSQL + ' AND  FunctionState= @ckFunctionState'

     END

--- Add Where Key Word ---

--- Run SQL Begin ---

EXECUTE sp_executesql @strSQL,

         N'   @ckScoreSettingID INT,

              @ckFunctionID INT,

              @ckOperationID INT,

              @ckRoleTypeID INT,

              @ckBBSTypeID INT,

              @ckScore INT,

              @ckBB INT,

              @ckBuyType INT,

              @ckFunctionState INT',

              @ckScoreSettingID=@ScoreSettingID,

              @ckFunctionID=@FunctionID,

              @ckOperationID = @OperationID,

              @ckRoleTypeID = @RoleTypeID,

              @ckBBSTypeID  = @BBSTypeID,

              @ckScore = @Score,

              @ckBB = @BB,

              @ckBuyType = @BuyType,

              @ckFunctionState = @FunctionState

--- Run SQL End ---

 

一点说明:

此存储过程会 据数据层的类有没有传递相应的参数值进来而动态创建查询语句,然后用系统自带的存储过程执行sql语句,用系统存储过程执行sql语句的好处是可以自动转义字符。而动态创建查询语句的好处,就非常大了,这会省下 们写很多种条件判断,尤其是对那些字段比较多的表来讲,一个排列组合下来的情况太多了,而利用存储过程动态创建sql语句所作的判断数和字段数基本上是一致的,这里会给入参赋初始值,如果不等于初始值就说明数据层类有传递参数进来,这样就加上相应条件字符的查询条件。

一、 数据层类:

using System;

using System.Collections;

using System.Data;

using System.Data.SqlClient;

using Town.Data;

using Town.Log;

 

namespace Town.Com

{

     /// <summary>

     /// 功能:积分设置集合类

     /// 作者:Rexsp

     /// 创建日期:2004-01-14

     /// 修改者:

     /// 修改日期:

     /// </summary>

     public class ScoreSettingCollection

     {

         #region 私有成员

         private ArrayList members;

         #endregion

 

         #region 构造函数

         /// <summary>

         /// 构造函数

         /// </summary>

         public ScoreSettingCollection()

         {

         }

         #endregion

 

         #region 公共属性

         /// <summary>

         /// Operation对象的个数

         /// </summary>

         public int Count

         {

              get

              {

                   if( members != null )

                       return members.Count;

                   else

                       return 0;

              }

         }

         #endregion

 

         #region 索引

         /// <summary>

         /// 索引

         /// </summary>

         public ScoreSetting this[int index]

         {

              get

              {

                   if ( members != null )

                       return (ScoreSetting)( members[index] );

                   else

                       return null;

              }

         }

         #endregion

 

         #region 私有方法

         /// <summary>

         /// 添加Operation到OperationCollection集合

         /// </summary>

         private void Add(ScoreSetting scoreSetting)

         {

              if ( members == null )

                   members = new ArrayList();

              members.Add( scoreSetting );

         }

         #


  #region 公共方法

         /// <summary>

         /// 据不同条件取得积分设置

         /// </summary>

         /// <param name="functionID">功能ID</param>

         /// <param name="operationID">操作ID</param>

         /// <param name="roleTypeID">角色ID</param>

         /// <param name="bBSTypeID">版块类型DI</param>

         /// <param name="score">积分</param>

         /// <param name="bB">币币</param>

         /// <param name="buyType">购买类型</param>

         /// <param name="functionState">功能状态</param>

         /// <returns></returns>

         public bool GetSpecialInfo(int functionID,int operationID,int roleTypeID,int bBSTypeID,int score,int bB,int buyType,int functionState)

         {

              SqlDataAdapter dataAdapter = null;

              Database data = new Database("Town");

              #region 创建参数

              ArrayList sqlParameterList=new ArrayList();

              if(functionID!=-1)

                   sqlParameterList.Add(data.MakeInParam("@FunctionID",  SqlDbType.Int, 4,    functionID));

              if(operationID!=-1)

                   sqlParameterList.Add(data.MakeInParam("@OperationID",  SqlDbType.Int, 4,   operationID));

              if(roleTypeID!=-1)

                   sqlParameterList.Add(data.MakeInParam("@RoleTypeID",  SqlDbType.Int, 4,    roleTypeID));

              if(bBSTypeID!=-1)

                   sqlParameterList.Add(data.MakeInParam("@BBSTypeID",  SqlDbType.Int, 4,     bBSTypeID));

              if(score!=-1)

                   sqlParameterList.Add(data.MakeInParam("@Score",  SqlDbType.Int, 4,    score));

              if(bB!=-1)

                   sqlParameterList.Add(data.MakeInParam("@BB",  SqlDbType.Int, 4,  bB));

              if(buyType!=-1)

                   sqlParameterList.Add(data.MakeInParam("@BuyType",  SqlDbType.Int, 4,  buyType));

              if(functionState!=-1)

                   sqlParameterList.Add(data.MakeInParam("@FunctionState",  SqlDbType.Int, 4, functionState));

 

              SqlParameter[] prams= new SqlParameter[sqlParameterList.Count];

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

              {

                   prams[i]=(SqlParameter)sqlParameterList[i];

              }

              #endregion

              try

              {

                   data.RunProc("GetScoreSetting", prams, out dataAdapter);

                   DataSet dataSet = new DataSet();

                   dataAdapter.Fill(dataSet,"table");

                   dataAdapter.Dispose();

                   if(dataSet.Tables["table"].Rows.Count == 0)

                   {

                       dataSet.Clear();

                       dataSet.Dispose();

                       return false;

                   }

                   else

                   {

 

                       foreach(DataRow dr in dataSet.Tables["table"].Rows)

                       {

                            ScoreSetting SS = new ScoreSetting();

                            SS.ID= Int32.Parse(dr["ScoreSettingID"].ToString().Trim());

                            SS.FunctionID= Int32.Parse(dr["FunctionID"].ToString().Trim());

                            SS.OperationID= Int32.Parse(dr["OperationID"].ToString().Trim());

                            SS.RoleTypeID= Int32.Parse(dr["RoleTypeID"].ToString().Trim());

                            SS.BBSTypeID= Int32.Parse(dr["BBSTypeID"].ToString().Trim());

                            SS.Score= Int32.Parse(dr["Score"].ToString().Trim());

                            SS.BB= Int32.Parse(dr["BB"].ToString().Trim());

                            SS.BuyType= Int32.Parse(dr["BuyType"].ToString().Trim());

                            SS.FunctionState= Int32.Parse(dr["FunctionState"].ToString().Trim());

                            Add(SS);

                       }

 

                       dataSet.Clear();

                       dataSet.Dispose();

 

                       return true;

                   }

              }

              catch (Exception ex)

              {

                   Error.Log("Town", ex.ToString());

                   dataAdapter.Dispose();

                   return false;

              }

              finally

              {

                   data.Close();

                   data.Dispose();//释放Database

              }

         }

         #endregion

 

     }

}

 

一点说明:

数据层类分类的代码分了六块:私有成员、构造函数、公共属性、索引、私有方法、公有方法。这里为类建立了索引,这是集合类的必须元素。然后有一个私有方法,作用是把对象加到集合中,公有方法就是一个查询方法,上面的例子中是通过参数传的,其实也可以用属性传。这里作了个约定,如果传进的值为-1便认为此变量不起作用,基本跟存储过程中的思想是一样的。这个例子中的ScoreSetting对象是另外一个独立的类,如下:

using System;

using System.Data;

using System.Data.SqlClient;

using Town.Data;

using Town.Log;

using System.Collections;

namespace Town.Com

{

     /// <summary>

     /// 功能:积分类

     /// 作者:Rexsp

     /// 创建日期:2004-01-14

     /// 修改者:

     /// 修改日期:

     /// </summary>

     public class ScoreSetting

     {

        

         #region 私有成员

         /// <summary>

         /// 分值设置ID

         /// </summary>

         private int id=-1;

         /// <summary>

         /// 功能ID

         /// </summary>

         private int functionID=-1;

          /// <summary>

         /// 操作ID

         /// </summary>

         private int operationID=-1;

         /// <summary>

         /// 角色类型ID

         /// </summary>

         private int roleTypeID=-1;

         /// <summary>

         /// 版块类型ID

         /// </summary>

         private int bBSTypeID=-1;

         /// <summary>

         /// 积分

         /// </summary>

         private int score=-2000000000;

         /// <summary>

         /// 币币

         /// </summary>

         private int bB=-2000000000;

         /// <summary>

         /// 购买类型

         /// </summary>

         private int buyType=-1;

         /// <summary>

         /// 功能状态

         /// </summary>

         private int functionState=-1;

         /// <summary>

         /// 是否更新分值

         /// </summary>

         #endregion

 

         #region 公有属性

 

         /// <summary>

         /// 积分设置DI

         /// </summary>

         public int ID

         {

              get{return id;}

              set{id=value;}

         }

         /// <summary>

         /// 功能ID

         /// </summary>

         public int FunctionID

         {

              get{return functionID;}

              set{functionID=value;}

         }

         /// <summary>

         /// 操作ID

         /// </summary>

         public int OperationID

         {

              get{return operationID;}

              set{operationID=value;}

         }

         /// <summary>

         /// 角色类型

         /// </summary>

         public int RoleTypeID

         {

              get{return roleTypeID;}

              set{roleTypeID=value;}

         }

         /// <summary>

         /// 版块类型

         /// </summary>

         public int BBSTypeID

         {

              get{return bBSTypeID;}

              set{bBSTypeID=value;}

         }

         /// <summary>

         /// 积分

         /// </summary>

         public int Score

         {

              get{return score;}

              set{score=value;}

         }

         /// <summary>

         /// 币币

         /// </summary>

         public int BB

         {

              get{return bB;}

              set{bB=value;}

         }

         /// <summary>

         /// 购买类型 0- 不是购买类型  1 - 一次性购买 2-反复购买

         /// </summary>

         public int BuyType

         {

              get{return buyType;}

              set{buyType=value;}

         }

         /// <summary>

         /// 购买状态:0-无此功能 1-有此功能 2-需要购买

         /// </summary>

         public int FunctionState

         {

              get{return functionState;}

              set{functionState=value;}

         }

         #endregion

         #region 构造函数

         public ScoreSetting()

         {

         }

         /// <summary>

         /// 重载构造函数

         /// </summary>

         /// <param name="id">积分设置ID</param>

         public ScoreSetting(int id)

         {

              this.id=id;

         }

         #endregion

 

         #region 公共方法

         /// <summary>

         /// ID获得积分设置信息

         /// </summary>

         /// <returns>成功true,失败false</returns>

         public bool GetInfoByID()

         {

           //代码略

          }

 

         /// <summary>

         /// 添加积分设置

         /// </summary>

         /// <returns>成功true,失败false</returns>

         public bool Add()

         {

              //代码略

         }

         /// <summary>

         /// 编程积分设置

         /// </summary>

         /// <returns>成功返回true,失败返回false</returns> 

         public bool Edit()

         {

              //代码略

         }

         /// <summary>

         /// 删除积分设置

         /// </summary>

         /// <returns>成功返回true,失败返回false</returns>

         public bool Remove()

         {

              //代码略

     }

}

 

一点说明:这个类包含四部分,私有成员、构造函数、公共属性、公共方法,私有成员与数据库表的字段是对应的,属性与私有成员相对应。构造函数会初始数据表的key键,当然也可以重载构造函数初始另外的私有成员。这个类包含四个方法,也就是数据的四种操作:读、写、删、改。

 

一、表示层(UI层)

这一层主要是读取数据了。基本上会 据需求填充到不同的服务器控件中。

 

              ScoreSettingCollection ssc = new ScoreSettingCollection();

              FunctionCollection funcc = new FunctionCollection();

              funcc.GetInfoByFunctionName("版名管理");

              int functionID=funcc[0].ID;

              ssc.GetSpecialInfo(functionID,0,roleTypeID,bBSTypeID,-1,-1,-1,-1);

              int sscCount=ssc.Count;

 

 

 

上面的这段代码就是数据读取过程, sscCount可以判断有没有得到数据。在得到数据的前提下填充控件之前,是把这一条条的数据重新循环组成一个DataTable然后再绑定数据。

 

  我晕,本来以为一下子可以贴出来,不想还有限制,真麻烦,一篇文章贴子六次。嘿嘿!

  MSN:yubo@x263.net  有问题可以一起探讨

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值