当前位置:首页 > 网络编程 > WEB编程 > ASP.net >  扩展SqlDataSource 3

 扩展SqlDataSource 3

点击次数:26 次 发布日期:2008-11-26 11:48:08 作者:源代码网
源代码网推荐      如果不仅需要在输入条件为空时检索出所有记录,而且在输入条件至少一个不为空时能够根据输入的值检索符合条件的记录,那么仅仅通过在页面声明SelectCommand,然后声明一些SelectParameter参数和控件进行绑定时做不到的。因为在这种情况下,SelectCommand已经不是一成不变的了。
源代码网推荐  
源代码网推荐  那么,我们可能会放弃使用SqlDataSource,而拼凑Sql语句。
源代码网推荐  
源代码网推荐  但是,拼凑Sql通常是比较繁琐的,而且在不同场景下拼凑的Sql的代码很难复用。因此扩展SqlDataSource使其能够支持这种需要,是很实用的。
源代码网推荐  
源代码网推荐  那么怎样扩展才能够支持到这种需要呢?
源代码网推荐  首先,需要能够动态生成SelectCommand,而这个难点已经在SecuritySqlDataSource已经解决了。
源代码网推荐  然后,考虑到SelectParameter集合已经能够支持6种来源的Parameter(ControlParameter,CookieParameter,FormParameter,QueryStringParameter,ProfileParameter,SessionParameter)能够对不能来源的Paramter提供很好的支持,而且ControlParameter对丰富的页面控件提供很好的支持,能够避免我们通过别的解决方案解决这个问题时碰到的难题(如对TextBox控件的取值和DropDownList控件的取值是不同的),所以决定把这些参数利用起来,并且给这些已有的参数类型提供一些属性。例如:给它添加一个Pattern属性,来描述该参数的值将在SelectCommand种被Format成什么子句,来代替SelectCommand中State=@State这样的子句,简单的,Pattern值类似这样:State={0}.另外,考虑到经常碰到的动态构造子句的问题,如Title为空时,生成1=1,Title不为空时,生成au_id in (select ta.au_id from titleauthor ta where ta.title_id in (select title_id from titles where {0}))其中{0}将被Pattern的值(title={0})代替.分析这种情况,我们引入Group属性,用来将每个子查询分组。也就是每个查询参数一定属于每个组。然后在每组的查询子句构造完成后抛出一个事件SearchConditionBuilded,在事件中来构造上面的语句,这样解决了动态构造SelectCommand的问题。
源代码网推荐  再对上面的解决办法进一步优化,我们把Group属性抽取出来,变成节点,这样就不用在每个查询参数都设置Group属性,而把属于该Group组的查询参数都置于该节点之下。同时,把原来在SearchConditionBuilded事件中处理的给子查询做处理的语句抽取出来,变成一个属性,也叫Pattern。在上面举的场景中,Pattern的值就是au_id in (select ta.au_id from titleauthor ta where ta.title_id in (select title_id from titles where {0})),然后给每个组设置一个DefaultCondition,表示这个子查询中如果所有的查询参数都为空时,该子句生成的缺省条件.同时为了区别个组,给组增加一个属性Name.
源代码网推荐  所以,最后的结果是类似这样
源代码网推荐  
源代码网推荐  到这里为止,前面提出的问题都已经得到了解决.
源代码网推荐  
源代码网推荐  下面介绍代码如果实现
源代码网推荐  
源代码网推荐  首先建立SqlDataSource类,使之继承SecuritySqlDataSource.
源代码网推荐  public class SqlDataSource : SecuritySqlDataSource
源代码网推荐  
源代码网推荐  再建立SqlDataSourceView,使之继承SecuritySqlDataSourceView
源代码网推荐  SqlDataSourceView : SecuritySqlDataSourceView
源代码网推荐  
源代码网推荐  Override CreateDataSourceView方法,使SqlDataSource类和SqlDataSourceView类关联起来
源代码网推荐   protected override System.Web.UI.WebControls.SqlDataSourceView CreateDataSourceView(string viewName)
源代码网推荐   ...{
源代码网推荐   SqlDataSourceView sqlDataSourceView = new SqlDataSourceView((System.Web.UI.WebControls.SqlDataSource)this, viewName, HttpContext.Current);
源代码网推荐   return sqlDataSourceView;
源代码网推荐   }
源代码网推荐  
源代码网推荐  
源代码网推荐  因为需要建立一个Pattern节点,所以在SqlDataSource中增加一个属性Pattern
源代码网推荐   private SearchGroups patterns = new SearchGroups();
源代码网推荐   [Category("Search"),
源代码网推荐   Description("查询模式"),
源代码网推荐   PersistenceMode(PersistenceMode.InnerDefaultProperty),
源代码网推荐   DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
源代码网推荐   public SearchGroups Patterns
源代码网推荐   ...{
源代码网推荐   get ...{ return this.patterns; }
源代码网推荐   set ...{ this.patterns = value; }
源代码网推荐   }
源代码网推荐  
源代码网推荐  
源代码网推荐  而Pattern属性是一个复杂节点,Pattern的属性需要被持久化成子节点,所以SqlDataSource类需要增加这两个属性
源代码网推荐  
源代码网推荐   [ParseChildren(true)]
源代码网推荐   [PersistChildren(false)]
源代码网推荐  public class SqlDataSource : SecuritySqlDataSource
源代码网推荐  
源代码网推荐  
源代码网推荐  上面使用的SearchGroup中有一个重要的属性,它用来表示Pattern包含的组
源代码网推荐  
源代码网推荐   [ParseChildren(true, "Groups")]
源代码网推荐   [TypeConverter(typeof(ExpandableObjectConverter))]
源代码网推荐   public class SearchGroups
源代码网推荐   ...{
源代码网推荐   Private Property#region Private Property
源代码网推荐   private ArrayList groups;
源代码网推荐   #endregion
源代码网推荐  
源代码网推荐   Designer Exposed InnerProperty#region Designer Exposed InnerProperty
源代码网推荐   [
源代码网推荐   Category("Behavior"),
源代码网推荐   Description("查询组"),
源代码网推荐   NotifyParentProperty(true),
源代码网推荐   PersistenceMode(PersistenceMode.InnerDefaultProperty),
源代码网推荐   Editor(typeof(SearchGroupEditor), typeof(UITypeEditor)),
源代码网推荐   DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
源代码网推荐   ]
源代码网推荐   public ArrayList Groups
源代码网推荐   ...{
源代码网推荐   get
源代码网推荐   ...{
源代码网推荐   if (groups == null)
源代码网推荐   ...{
源代码网推荐   groups = new ArrayList();
源代码网推荐   }
源代码网推荐   return groups;
源代码网推荐   }
源代码网推荐   }
源代码网推荐   #endregion
源代码网推荐  }
源代码网推荐  
源代码网推荐   至于每组里的查询参数节点怎样实现,以及组节点的属性如果增加进来,由于属性较多,这里不一一解释,详细实现请参看代码
源代码网推荐  
源代码网推荐   扩展中遇到的问题:
源代码网推荐  如果自定义ServerControl的类在App_Code文件夹下,则注册时不能使用Assembly,否则会出错.这是因为App_Code文件夹编译后生成的Assembly命名是随机的.正确的做法是将类单独放在一个工程里,然后引用.或者注册时使用namespace注册,不要使用Assembly
源代码网推荐  自定义SeverControl在注册时不要使用强命名,这样会使该ServerControl中的复杂节点(即包含子节点的节点)注册不正确(原因不明).可行的做法是:使用Assembly的名称即可,去掉强命名
源代码网推荐  在SqlDataSource中,如果在其定义的事件(比如Selecting,Selected)中,更改SelectCommand是无效的.这是因为真正用来取数据的DBCommand在这些事件之前已经构造完成了,而更改后的SelectCommand不会用来重新生成DBCommand.
源代码网推荐  如果这定义的ServerControl包含集合属性,那么需要扩展该集合属性的编辑器,并在集合属性上指明该编辑器Editor(typeof(EditorName)),否则编辑完成后,编辑的值不会被持久化.并且扩展的编辑器完成后,如果更改了集合的字段,那么需要重新启动IDE,设计器才会正确显示修改会的字段.
源代码网推荐  在SqlDataSource中ParameterCollection是如何求解的呢?ParameterCollection有个GetValues方法,可以求解出所有Parameter的值,结果是IOrderedDictionary类型.求解出来的结果用来构造DBCommand.
源代码网推荐  
源代码网推荐  
源代码网推荐  
源代码网推荐  
源代码网推荐  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1489996
源代码网推荐  
源代码网推荐    做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。
源代码网推荐


源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华