慎用DataTable.DefaultView

今天在做项目的时候,遇到了一个比较奇怪的问题,下边是导致这个奇怪问题的代码:

 1         DataTable dt  =  (DataTable) this .Cache[ " Key " ];
 2          if  (dt  ==   null )
 3          {
 4            dt = Category.GetDataList();
 5            this.Cache.Insert("Key", dt);
 6        }

 7         DataView dv  =  dt.DefaultView;
 8          this .dl_Info.DataSource  =  dv;
 9          this .dl_Info.DataBind();
10
11         dv.RowFilter  =   " Depth=1 " ;
12          if  (dv.Count  ==   1 )
13              this .lbl_Message.Text  =  dv[ 0 ][ " nodeName " ].ToString();

假设:第4行代码执行后,dt中的数据有3条数据,我们将取到的数据放入Cache中,第7行代码得到一个DataView,我们将得到的DataView作为dl_Info(DataList控件)的数据源,第11行代码对DataView进行筛选,筛选后dv中的数据为1条。

上边的这段小代码,在Cache["Key"]值为null的时候,是正常的,一旦Cache["Key"]的值不是null,dl_Info的控件的数据源就不正确了,dl_Info的数据源变成了筛选后的数据,即1条数据。

刚开始怎么也想不明白,代码不长,也没有过多的复杂逻辑,数据怎么就不正常呢?后来用工具(.NET Reflector)查看了一下DataTable的DefaultView属性,才算明白怎么回事。DefaultView属性的反射代码为:
 1 [ResDescription( " DataTableDefaultViewDescr " ), Browsable( false )]
 2 public  DataView DefaultView
 3 {
 4    get
 5    {
 6        DataView defaultView = this.defaultView;
 7        if (defaultView == null)
 8        {
 9            if (this.dataSet != null)
10            {
11                defaultView = this.dataSet.DefaultViewManager.CreateDataView(this);
12            }

13            else
14            {
15                defaultView = new DataView(thistrue);
16                defaultView.SetIndex2("", DataViewRowState.CurrentRows, nulltrue);
17            }

18            defaultView = Interlocked.CompareExchange<DataView>(ref this.defaultView, defaultView, null);
19            if (defaultView == null)
20            {
21                defaultView = this.defaultView;
22            }

23        }

24        return defaultView;
25    }

26}

27  
28

看了这段代码,我们发现原来DataTable内部有一个的defaultView字段,在我们 第一次调用DataView dv = dt.DefaultView的时候,dt为我们生成一个新的DataView,并将生成的DataView赋值给defaultView字段, 第二次在执行DataView dv = dt.DefaultView这样的代码时,会将第一次生成的defaultView给传递出来,看到这里时,就明白了我在上边写的那段小代码为什么出问题了。

基于以上理由, 我们在使用DataTable的DefaultView的属性的时候,就要注意了,别和Cache同时使用,上边的小代码该成下边的样子,就能正常运行了
 1         DataTable dt  =  (DataTable) this .Cache[ " Key " ];
 2          if  (dt  ==   null )
 3          {
 4            dt = Category.GetDataList();
 5            this.Cache.Insert("Key", dt);
 6        }
 7         DataView dv  =   new  DataView(dt);
 8          this .ddl_Info.DataSource  =  dv;
 9          this .ddl_Info.DataBind();
10
11         dv.RowFilter  =   " Depth=1 " ;
12          if  (dv.Count  ==   1 )
13              this .lbl_Message.Text  =  dv[ 0 ][ " nodeName " ].ToString();
改动的地方在第7行。
如果您还有别的疑问,请给我留言。

转载于:https://www.cnblogs.com/fengfeng/archive/2008/03/27/1125225.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值