Home General

Numerical sorting in grid when using ToDump() with Util.ToExpando.

I've two questions about the difference between viewing in Rich Text (Hmtl) vs grid when using ToDump.

Question 1

Linqpad has a very handy feature where at runtime you can 'view in grid' and then sort by a column. However if the data you are viewing is from an object which has been customised to exclude some columns using ToDump and Util.ToExpando, then the sorting is purely alphabetically.

To illustrate this problem, run the following code

void Main()
{
    List<Test> testData = new List<Test>
        {
            new Test { Name = "Alpha"  , Value = 1m  , Others = "Category A" },
            new Test { Name = "Beta"   , Value = 100m, Others = "Category B" },
            new Test { Name = "Gamma"  , Value = 50m , Others = "Category C" },
            new Test { Name = "Delta"  , Value = 3m  , Others = "Category D" },
            new Test { Name = "Epsilon", Value = 9m  , Others = "Category E" }

        };

    testData.Dump(false);
    testData.Dump(true);
}


public class Test
{
    public string? Name;
    public decimal? Value;
    public string? Others;

    object ToDump() => Util.ToExpando(this, exclude: "Others");
}

When you sort by value you get this

I can work around this by changing the query using
object ToDump() => new { Name, Value };

but that either requires knowing before-hand that I am going to want to sort the data or else interrupts the workflow and I have to amend the code and re-run the query.

The same thing applies to the formatting of the columns.

****I would not have bothered posting this, except for the fact that the normal non-grid view knows that the Value Column is a decimal and was wondering why the grid doesn't.

Question 2

If I take the same query above and remove the custom ToDump method in Test and replace it with

 static object ToDump(object x)
 {
    return x is Test ? Util.ToExpando(x, exclude: "Others") : x ;
 }

This correctly excludes the Others column when viewing in Html, but doesn't exclude it when viewing in a Grid. Why?

Comments

  • Question 2

    I reported similar bug looong time ago...

  • Type of Util.ToExpando() is System.Dynamic.ExpandoObject, so there are no properties.

    var t = new Test("s", 1);
    var e = Util.ToExpando(t);
    e.GetType().Dump();
    
    t.Dump();
    
    record Test(string StrVal, int IntVal);
    
  • Type of Util.ToExpando() is System.Dynamic.ExpandoObject, so there are no properties.

    That was my initial thought and hence that nothing could be done, but the normal html display knows the type (at least when it is a List of ExpandoObjects) so why not the data grid?

  • Regarding question 1, I had a look at the internals of LinqPad to see what is going on and I think this could be fixed with a slight performance hit.

    At the moment, Linqpad builds a DataTable from the list of ExpandObjects without checking the type of each column and hence each DataColumn is a string.

    https://share.linqpad.net/s5d5mn9v.linq is a benchmark script with an amended copy of this routine that sets the column type iff every non-null value for that column has the same type.

    The benchmark runs against 10000 records (using the demo database supplied with Linqpad but any database could be used).

    The results are as follows.

    I think this performance hit is worth the benefit for the following reasons.

    • It is only a 2% slowdown.
    • It is only a couple of milliseconds when processing 10,000 records
    • I would not be using ExpandObjects if I was that worried about performance.

    It is relying on the fact that at the point where this code is used by LinqPad the source has been converted to a list, so even if the original source was IQueryable we are not going to be hitting the database several times. Hence my benchmark is using a list.

    It is also relying on the fact that DataTable handles nulls, hence we do not need to worry about whether the columnType should be nullable or not.

    Are there any downsides that I have not considered?

    What do you think?

  • Thanks - that seems reasonable. I'll get it into next beta.

Sign In or Register to comment.