Разница между DataView.Sort и DataTable.OrderBy (). AsDataView ()? - PullRequest
1 голос
/ 07 октября 2010

У меня есть DataGridView, который связан с DataTable, который содержит столбец пользовательских типов, по которым мне нужно отсортировать.Этот пользовательский тип (MyCustomType) реализует IComparable<MyCustomType>, поэтому я хотел, чтобы сортировка работала.

Я попробовал 2 метода для создания 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 с поддержкой DataView - ?Почему это так?

Кроме того, кто-нибудь знает об относительной производительности DataView с без поддержки LINQ и LINQ?Похоже, что если нет огромного снижения производительности, нет больше причин использовать версию без поддержки LINQ.

Ответы [ 3 ]

1 голос
/ 23 декабря 2014

Я публикую сравнения для всех, кто интересуется, как Linq-DataView работает по сравнению с non-Linq-DataView, тем более что результаты меня удивили.Для этого теста, по крайней мере, старый DataView на порядок быстрее, чем DataView с поддержкой 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

Linq-DataView по сравнению с Linq-DataView для нетипизированного dtbl (секунд)

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()

OrderBy для v2 (с встроенным комментарием для 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)},
};

Если кто-нибудь когда-либо увидит это и может предложить способ отображения столбцов данных -> полевых лямбд, не полагаясь на функцию <>, возвращающуюдинамический тип, любое предложение будет приветствоваться.

0 голосов
/ 03 марта 2011

Когда вы вызываете .Sort в DataView, он сортирует этот конкретный экземпляр объекта.Ваш второй метод фактически создает новый объект и присваивает значение переменной dv.Это может быть критической разницей.

РЕДАКТИРОВАТЬ : Не ваш второй метод специально, так как вы не назначаете, а затем переназначаете.Но если бы у вас был существующий DataView, а затем переназначили его, используя метод OrderBy, то у вас был бы сценарий, который я предложил.

Извините, я не был так ясен, как следовало бы.

0 голосов
/ 03 марта 2011

DataView.Sort - это метод, встроенный в класс DataView, тогда как .OrderBy - это расширение.

...