在 做Asp.NET开发的时候经常用到DataList、Repeater等,用这些控件的时候经常用到数据邦定,很多程序员都是按照MS提供的方 法<%#DataBinder.Eval(Container.DataItem,"xxx") %>进行邦定,经常听人说这样邦定效率低,那么到底哪里引起的效率低呢?不妨大家打开MS的代码来看看他是这么实现这个数据邦定的,这样一切都清楚 了。DataBinder是System.Web.UI中的一个静态类。首先看一下它的Eval方法:

public static object Eval (object container, string expression)
{
     if (expression == null)
      {
          throw new ArgumentNullException("expression");
      }
      expression = expression.Trim();
     if (expression.Length == 0)
      {
          throw new ArgumentNullException("expression");
      }
     if (container == null)
      {
          return null;
      }
     return DataBinder.Eval(container, expression.Split(DataBinder.expressionPartSeparator));
}

这个方法调用了另外一个重载的Eval方法我们接着看这个方法:

private static object Eval (object container, string[] expressionParts)
...{
     object obj1 = container;
     for (int num1 = 0;(num1 < expressionParts.Length) && (obj1 != null); num1++)
     ...{
          string text1 = expressionParts[num1];
          if (text1.IndexOfAny(DataBinder.indexExprStartChars) < 0)
          ...{
                obj1 = DataBinder.GetPropertyValue(obj1, text1);
           }
          else
          ...{
                obj1 = DataBinder.GetIndexedPropertyValue(obj1, text1);
           }
      }
     return obj1;
}

在这个方法中有一个GetIndexedPropertyValue方法是处理索引用的,一般邦定用到的是上边的GetPropertyValue方法。继续看GetPropertyValue方法:

public static object GetPropertyValue (object container, string propName)
{
     if (container == null)
      {
          throw new ArgumentNullException("container");
      }
     if (string.IsNullOrEmpty(propName))
      {
          throw new ArgumentNullException("propName");
      }
     object obj1 = null;
      PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(container).Find(propName, true);
     if (descriptor1 == null)
      {
          throw
new HttpException(SR.GetString("DataBinder_Prop_Not_Found", new
object[]{container.GetType().FullName, propName}));
      }
     return descriptor1.GetValue(container);
}

晕~~
这个方法中利用TypeDescriptor的GetProperties方法将邦定对象反射然后用GetValue获取我们想要的值!
看到这里我想大家都已经看清楚了,原来当我们调用<%#DataBinder.Eval(Container.DataItem,"xxx")
%>时是将Container.DataItem反射然后用GetValue取值的,也就是说如果你页面中有多个DataBinder的话每个都要
反射、取值!晕倒~
反射是非常消耗资源而且效率低下的这个不用我说了。对于反射只有在动态加载程序集或者在未知数据类型的情况下不得已才用得,显然我们对我们要邦定的数据既
不需要动态加载也不是未知数据类型,那么完全没有必要用这个既浪费资源又非常慢的技术。看来MS提供的这个DataBinder.Eval玩意儿真不是什
么好东西,呵呵。

不过咱们稍微改进一下效率可以提高数十倍甚至数百倍。既然大家知道瓶颈出在反射上那咱们就不用反射,怎么办呢?答案是不用DataBinder.Eval邦定,具体如下:


一种方法:这种方法好多地方介绍过。用在邦定页面上把Container.DataItem转换为邦定类型,如:我们在用DataTable做数据源的时
候其实Container.DataItem就是DataRowView那么把Container.DataItem转换为DataRowView不就可
以用索引直接取值了吗?:<%#((DataRowView)Container.DataItem)["xxx"]%>
哈哈,这样效率有大幅度提升,尤其在数据量大的时候。

第二种方法:上一种方法虽好但是每次取值的时候都要转换一下,还不够完美。能不能一下
转过来然后再所有邦定中直接取呢?答案是肯定的!我们可以在DataList、Repeater的ItemCreated事件中做文章,我们在定义一个
protected 变量,变量类型为邦定数据类型。如protected DataRowView Info =null;
然后再ItemCreated中进行转换付值。最后在前台邦定时写成?<%#Info ["xxx"]%>代码:

protected DataRowView Info = null;
        protected void RepInfoList_ItemCreated(object sender, RepeaterItemEventArgs e)
         {
             Info = e.Item.DataItem as DataRowView;
         }

如果用户用IList<T>做数据源就更简单了:

protected BbsInfo Info =null;
protected void RepInfoList_ItemCreated(object sender, RepeaterItemEventArgs e)
{
         Info = e.Item.DataItem as BbsInfo
}

前台邦定变为<%#Info.Title%>


结:MS确实提供了很多方便快捷的功能,但是方便和快捷的背后是性能的损失,这些方便快捷的方法只是提供给一些初级阶段的程序员来更快的完成一些工作,他
们并不注重效率。但是如果要求高效率那么就要自己动手,这就要求我们要对.NET要有深刻的认识,所以要想成为高手必须深入理解.NET机理,做到随心所
欲。

ASP.NET中数据邦定效率问题的一点看法 - 转载(自由的天空)的更多相关文章

  1. [WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板

      引言 书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate)   切换模板的两种方式:   使用DataTemplateSelecto ...

  2. ASP.NET中数据棒图,饼图,柱状图的实现

    Web中绘制图形的方法大致有: 1. VML方式:功能强大,但是非常麻烦. 推荐:http://www.elook.net.cn/vml/ 2.使用控件:Dandus, Aspose.chart,Co ...

  3. [WPF系列]-数据邦定之DataTemplate 使用 DataTrigger 来应用属性值

    使用 DataTrigger 来应用属性值 当前表示不会告诉我们某个 Task 是家庭任务还是办公室任务.记住 Task 对象拥有类型为 TaskType 的 TaskType 属性,该类型是一个枚举 ...

  4. [WPF系列]-数据邦定之DataTemplate 对分层数据的支持

    到目前为止,我们仅讨论如何绑定和显示单个集合. 某些时候,您要绑定的集合包含其他集合. HierarchicalDataTemplate 类专用于 HeaderedItemsControl 类型以显示 ...

  5. [WPF系列]-数据邦定之DataTemplate简介

    引言 WPF 数据模板化模型为定义数据的表示形式提供了很大的灵活性.WPF 控件有支持自定义数据表示形式的内置功能.首先介绍下如何定义Datatemplate,然后再介绍其他数据模板化功能,例如根据自 ...

  6. 有关Asp.net 中数据请求的处理的新认知:利用httpHandlers

    转自csdn:HttpHandler    HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到Http ...

  7. [WPF系列]-数据邦定之DataTemplate 对 ItemsControl 进行样式和模板处理

    引言   即使 ItemsControl 不是 DataTemplate 所用于的唯一控件类型,将 ItemsControl 绑定到集合仍然很常见. 在 DataTemplate 中有哪些内容一节中, ...

  8. fastreport for .net 数据邦定

    C# Code: private void button4_Click(object sender, EventArgs e){   //打印主从表数据    string file = Applic ...

  9. Linux中解压缩命令gzip和unzip的一点说明

    inux中解压缩命令gzip和unzip的一点说明 转载 2014年10月29日 20:37:35 20741   Linux 常用的压缩命令有 gzip 和 zip,两种压缩包的结尾不同:zip 压 ...

随机推荐

  1. GitHub下载的 Git Shell中出现的字符支持警告,将字体修改为新宋体即可

    ——解决办法: 将命令行字体修改为新宋体就可以了. 文章引用:http://www.cnblogs.com/veryinf/archive/2012/10/26/2740899.html

  2. 如何解决EditText使用时,点击外侧系统键盘不消失的bug

    在使用viewPager和EditText一起使用的时候,突然出现了一个bug,在点击EditText(此EditText是在ViewPager的Fragment中) 我在切换ViewPager的时候 ...

  3. 关于JAVA EE项目在WEB-INF目录下的jsp页面如何访问WebRoot中的CSS和JS文件

    找了这么久资料,总算解决了 感谢博客园:http://www.cnblogs.com/xsht/p/5275081.html 感谢百度:http://zhidao.baidu.com/link?url ...

  4. DEV GridControl.TableView FocusedRow选中行背景颜色

    上次修改了TableView.RowStyle,导致了一个问题:覆盖了GridControl默认的选中行颜色. 于是需要重写选中行的颜色. 刚开始的想法是: <dxg:TableView> ...

  5. Hibernate实现向数据库插入一条数据全过程(Study By Example)

    1.数据库(直接在cmd下进入数据库操作亦可) (1)启动Navicat for MySQL (2)打开连接,创建一个数据库,名为testdb (3)新建表user1,表结构如图所示 2.数据库池 ( ...

  6. 使用C语言将IE收藏夹生成HTML

    IE收藏夹里收藏的链接很多,查找也不方便,使用C编写一个小工具,可以将收藏夹里的链接文件生成到一个HTML文件上. 源码还有许多地方需要优化,后续我会优化,先分享出来.目的主要是为了练习C语言,这个代 ...

  7. 学习笔记Jmail收发邮件

    一.利用Jmail发送邮件  1/// <summary> 2/// 利用Jmail发送邮件 3/// </summary> 4private void SendMailByJ ...

  8. (转)js activexobject调用客户机exe文件

    原文地址:http://blog.csdn.net/jiafugui/article/details/5364210 function Run(strPath) { try { var objShel ...

  9. 《转》简述c语言的优缺点

    C语言是1972年由美国的Dennis Ritchie设计发明的,到1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言.再到1970到80年代,C语言被广泛应用.这短短的几十年 ...

  10. [转]Jenkins Xcode打包ipa

    本地打包. 如果Mac 上没有安装brew.先安装:ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/ins ...