代码之家  ›  专栏  ›  技术社区  ›  We Are All Monica

dataview.sort和datatable.orderby().asdataview()之间的区别?

  •  1
  • We Are All Monica  · 技术社区  · 15 年前

    我有一个 DataGridView 它绑定到 DataTable 它包含一列我需要排序的自定义类型。此自定义类型( MyCustomType 工具 IComparable<MyCustomType> 这就是我希望排序工作的方式。

    我尝试了两种方法来创建 DataView 我将使用它作为网格的数据源:

    MyDataTable dt = new MyDataTable();
    DataView dv = new DataView(dt);
    dv.Sort = "MyCustomField";
    

    这并不能真正正常工作——它“几乎”可以工作,但有时我的行不能正确排序。

    第二种方法:

    MyDataTable dt = new MyDataTable();
    DataView dv = dt.OrderBy(row => row.MyCustomField).AsDataView();
    

    这似乎是我想要的。我的问题是,这两种方法有什么区别?有没有可能 DataView.Sort 用我的 IComparable<T> 实现,并启用LINQ 数据视图 ?为什么会这样?

    此外,是否有人知道非LINQ启用和LINQ启用的相对性能? 数据视图 S?看起来,如果没有一个巨大的性能冲击,就不再有任何理由使用非LINQ启用版本了。

    3 回复  |  直到 11 年前
        1
  •  0
  •   Joe Enos    15 年前

    当你打电话 .Sort 在数据视图上,它对对象的这个特定实例进行排序。第二种方法实际上创建了一个全新的对象并将其分配给 dv 变量。这可能是一个关键的区别。

    编辑 :不是您的第二个方法,因为您没有分配,所以重新分配。但是,如果您有一个现有的数据视图,然后使用orderby方法重新分配它,那么您将拥有我建议的场景。

    不好意思,我不太清楚。

        2
  •  1
  •   egc    11 年前

    我在为其他人发布比较,想知道LinqDataView与非LinqDataView的性能如何,特别是因为结果让我吃惊。对于这个测试,旧数据视图至少比启用LINQ的数据视图快一个数量级。

    v1: Linq-DataView, on-the-fly sort string -> OrderBy/ThenBy via Field<dynamic>()
    v2: Linq-DataView, on-the-fly via mapped Field<type>()
    v3: Linq-DataView, hard-coded OrderBy/ThenBy
    v4: non-Linq DataView w/sort string
    

    非类型化DTBL的Linq DataView与非Linq DataView(秒)

    03.411  v1 = dtbl.AsEnumerable().OrderBy("T30y, Dat desc").AsDataView();
    02.561  v2 = dtbl.AsEnumerable().OrderBy(dtbl, "T30y, Dat desc").AsDataView();
    01.573  v3 = dtbl.AsEnumerable().OrderBy(y=>y.Field<decimal>("T30y"))
                                    .ThenByDescending(y=>y.Field<DateTime>("Dat")).AsDataView();
    00.214  v4 = new DataView(dtbl, "", "T30y, Dat desc", DataViewRowState.CurrentRows);
    
    02.403  v1: 100,000 iterations of Find()
    01.708  v2: 100,000 iterations of Find()
    01.173  v3: 100,000 iterations of Find()
    00.261  v4: 100,000 iterations of Find()
    

    v2的orderby(带有v1的内联注释)

    static public EnumerableRowCollection<DataRow>
        OrderBy( this EnumerableRowCollection<DataRow> ys, DataTable dtbl, string sort )
    {
        OrderedEnumerableRowCollection<DataRow> oys = null;
        foreach ( string s in (sort ?? "").Split(new []{", "}, StringSplitOptions.None) )
        {
            int n = s.IndexOf(" desc");
            string x = n!=-1 ? s.Substring(0, n) : s;
            Type typ = dtbl.Columns[x].DataType;
            Func<DataRow,dynamic> vfn = y=>yget[typ](y,x); // v1: vfn = y.Field<dynamic>(x)
    
            if ( oys==null )
                 oys = s.Contains(" desc") ? ys.OrderByDescending(vfn) : ys.OrderBy(vfn);
            else oys = s.Contains(" desc") ? oys.ThenByDescending(vfn) : oys.ThenBy(vfn);
        }
        return oys ?? ys;
    }
    
    static Dictionary<Type,Func<DataRow,string,dynamic>>
        yget = new Dictionary<Type,Func<DataRow,string,dynamic>>
    {
        {typeof(bool),     (y,x)=>y.Field<bool>(x)},
        {typeof(short),    (y,x)=>y.Field<short>(x)},
        {typeof(int),      (y,x)=>y.Field<int>(x)},
        {typeof(string),   (y,x)=>y.Field<string>(x)},
        {typeof(decimal),  (y,x)=>y.Field<decimal>(x)},
        {typeof(float),    (y,x)=>y.Field<float>(x)},
        {typeof(double),   (y,x)=>y.Field<double>(x)},
        {typeof(DateTime), (y,x)=>y.Field<DateTime>(x)},
        {typeof(TimeSpan), (y,x)=>y.Field<TimeSpan>(x)},
    };
    

    如果有人看到了这一点,并且可以建议一种映射数据列的方法--不依赖func返回动态类型的field lambdas,那么任何建议都是最受欢迎的。

        3
  •  -1
  •   Josh M.    15 年前

    dataview.sort是一个内置于dataview类中的方法,而.orderby是一个扩展。