DataGrid dynamic: error with DateTime?

Hello.

I am working with the example @ https://blazor.radzen.com/datagrid-dynamic
I am changing the code of the method 'GetColumnPropertyExpression' as follows:

            var expression = $@"it[""{name}""].ToString()";

            if (type == typeof(decimal))
            {
                return $"decimal.Parse({expression})";
            }
            if (type == typeof(decimal?))
            {
                return $"string.IsNullOrEmpty({expression}) ? decimal.MinValue  : decimal.Parse({expression})";
            }
            if (type == typeof(int))
            {
                return $"int.Parse({expression})";
            }
            if (type == typeof(int?))
            {
                return $"string.IsNullOrEmpty({expression}) ? int.MinValue  : int.Parse({expression})";
            }
            if (type == typeof(DateTime))
            {
                return $"DateTime.Parse({expression})";
            }
            if (type == typeof(DateTime?))
            {
                return $"string.IsNullOrEmpty({expression}) ? DateTime.MinValue  : DateTime.Parse({expression})";
            }

            return expression;

Now when I try to sort the column of type 'DateTime?' via the LoadData event and OrderBy clause I get an exception. What am I doing wrong?

Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost: Error: Unhandled exception in circuit 'DeigaU6ki_VuVY27AOuz9N7fRWwNEGVV4Lc_oeUq3-k'.

No applicable indexer exists in type 'ITool' (at index 26)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseElementAccess(Expression expr)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArithmetic()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOutKeyword()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArguments()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArgumentList()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseMemberAccess(Type type, Expression expression)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseTypeAccess(Type type, Boolean getNext)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIdentifier()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimaryStart()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArithmetic()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOutKeyword()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArguments()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArgumentList()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseFunctionNullPropagation()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIdentifier()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimaryStart()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArithmetic()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrdering(Boolean forceThenBy)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.InternalOrderBy(IQueryable source, ParsingConfig config, String ordering, Object comparer, Object[] args)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.OrderBy(IQueryable source, ParsingConfig config, String ordering, Object[] args)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.OrderBy[TSource](IQueryable`1 source, ParsingConfig config, String ordering, Object[] args)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.OrderBy[TSource](IQueryable`1 source, String ordering, Object[] args)
   at eToolBwa.Client.Pages.ToolPage.DynamicToolDataGrid_LoadData(LoadDataArgs args) in D:\misc\Burkhalter\etool\main\Project\src\eToolNg\eToolBwa\eToolBwa.Client\Pages\ToolPage.razor.cs:line 68
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Radzen.Blazor.RadzenDataGrid`1.InvokeLoadData(Int32 start, Int32 top)
   at Radzen.Blazor.RadzenDataGrid`1.ReloadInternal()
   at Radzen.Blazor.RadzenDataGrid`1.OnSort(EventArgs args, RadzenDataGridColumn`1 column)
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
   
   np(string.IsNullOrEmpty(it["DateOfPurchase"].ToString()) ? DateTime.MinValue  : DateTime.Parse(it["DateOfPurchase"].ToString())) asc

Thanks for any advice

Here is what worked for me:

@using System.Linq.Dynamic.Core

<RadzenDataGrid @bind-Value=@selectedItems Data="@data" TItem="IDictionary<string, object>" ColumnWidth="200px"
                        AllowFiltering="true" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true">
        <Columns>
            @foreach(var column in columns)
            {
                <RadzenDataGridColumn TItem="IDictionary<string, object>" Title="@column.Key" Type="column.Value"
                        Property="@GetColumnPropertyExpression(column.Key, column.Value)" >
                    <Template>
                        @context[@column.Key]
                    </Template>
                </RadzenDataGridColumn>
            }
    </Columns>
</RadzenDataGrid>

@code {
    IList<IDictionary<string, object>> selectedItems;

    public IEnumerable<IDictionary<string, object>> data { get; set; }

    public IDictionary<string, Type> columns { get; set; }

    public string GetColumnPropertyExpression(string name, Type type)
    {
        var expression = $@"it[""{name}""].ToString()";

        if (type == typeof(int))
        {
            return $"int.Parse({expression})";
        }
        else if (type == typeof(DateTime) || type == typeof(DateTime?))
        {
            return $"DateTime.Parse({expression})";
        }

        return expression;
    }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        columns = new Dictionary<string, Type>()
        {
            { "EmployeeID", typeof(int) },
            { "FirstName", typeof(string) },
            { "LastName", typeof(string) },
            { "HireDate", typeof(DateTime?) },
        };

        foreach (var i in Enumerable.Range(0, 50))
        {
            columns.Add($"Column{i}", typeof(string));
        }

        data = Enumerable.Range(0, 100).Select(i =>
        {
            var row = new Dictionary<string, object>();

            foreach (var column in columns)
            {
                row.Add(column.Key, column.Value == typeof(int) ? i : 
                    column.Value == typeof(DateTime?) ? i < 5 ? null : DateTime.Now.AddMonths(i) : $"{column.Key}{i}");
            }

            return row;
        });
    }
}