zoukankan      html  css  js  c++  java
  • 慎用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)]
     2public 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行。
    如果您还有别的疑问,请给我留言。
  • 相关阅读:
    OpenCV -- Mat 转 QImage 函数
    Qt--checkbox
    QT 发布release版本
    JS_0014:JS刷新页面
    JS_0013:JS获取文件后缀名
    JS_0012:JS从一个有规则的字符串中随机选择一个字符再循环生成一个新的无规则的字符串
    JQuery0016:JQuery等待页面全部加载完后执行代码块
    JQuery0015:JQuery查找指定元素并修改其属性
    JS_0011:通过JS给div添加html标签内容
    JS_0010:获取url中指定的参数
  • 原文地址:https://www.cnblogs.com/fengfeng/p/1125225.html
Copyright © 2011-2022 走看看