CSDN博客

img xuandme000

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

发表于2004/9/28 12:29:00  1055人阅读

分类: ASP.NET

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

相关文章推荐

img
取 消
img