Dropdowndatagrid loads all the records

I think I know how to handle this - it will be fixed in the next version!

This works if you uncoment the AsIQueryable():

@page "/"
@inherits IndexComponent
@layout MainLayout

<RadzenDropDownDataGrid TValue="int" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
                        AllowFiltering="true" AllowClear="true" Data="@countries" Change="@Change"
                        TextProperty="Name" ValueProperty="Id" @bind-Value="@selectedCountry" />

@code {
    public class Country2
    {
       public int Id { get; set; }
       public string Name { get; set; }
    }

    int selectedCountry = 1;
    IEnumerable<Country2> countries;

    protected override async Task OnInitializedAsync()
    {
       countries = new Country2[] {
          new Country2 { Id = 1, Name = "Country1" },
          new Country2 { Id = 2, Name = "Country2" },
       };//.AsQueryable();
    }

    void Change(object value)
    {
    }
}

but if not it fails with:

Error: System.InvalidOperationException: The binary operator Equal is not defined for the types 'System.Object' and 'System.Int32'.

at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)

at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)

at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)

at System.Linq.Dynamic.Core.Parser.ExpressionHelper.GenerateEqual(Expression left, Expression right)

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.Parse(Type resultType, Boolean createParameterCtor)

at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)

at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values)

at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(IQueryable source, ParsingConfig config, String predicate, Object[] args)

at Radzen.Blazor.RadzenDropDownDataGrid`1.SelectItemFromValue(Object value)

at Radzen.DropDownBase`1.OnParametersSetAsync()

at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()

at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

It will work in the next version:

1 Like

Just published 2.0.7 - let me know if you spot anything!

The previous bug seems to be fixed, but now something that was also working in v2.0.5 is broken:

System.NotSupportedException: Unable to cast the type 'Manu.Application.Serialization.Contracts.BusinessPartnerLocationDto' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ValidateAndAdjustCastTypes(TypeUsage toType, TypeUsage fromType, Type toClrType, Type fromClrType)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.CreateCastExpression(DbExpression source, Type toClrType, Type fromClrType)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.CastMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass41_0.<GetResults>b__1() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass41_0.<GetResults>b__0() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__31_0() at System.Data.Entity.Internal.LazyEnumerator1.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Radzen.Blazor.RadzenDropDownDataGrid1.LoadData(LoadDataArgs args)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Radzen.Blazor.RadzenGrid1.Reload() at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_0(Object state) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteSynchronously(TaskCompletionSource1 completion, SendOrPostCallback d, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<.cctor>b__23_0(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteBackground(WorkItem item)

I'll try to find out what's failing

Please send me a project where I can reproduce and debug this. You are still using the old EF (6.x), not EF Core, right?

Yes, I'm using EF 6.4.0.
I'll prepare a project

Here it is Vladimir:

http://85.214.40.25/rz/BlazorRadzenTests.zip

Also note that if countries = null instead of countries = context.Countries in line 26 of index.razor, it will give this error too:

InvalidOperationException: The binary operator Equal is not defined for the types 'System.Object' and 'System.Int32'.

Both issues fixed in latest update.

Thank you Vladimir! It is working now

BTW, the filtering for the enums in the datagrid is almost useless as a numeric control is displayed. However, usually the enum fields are the most important ones to filter by.

Is there any chance to implement a dropdown for filtering enums (using Enum.GetValues and EnumGetNames you can easily fill the dropdown).

If not, if you can create:

  • A virtual method in RadzenGridColumn where you put the default code for Type/Format inference for the RadzenGrid Grid cascading parameter
  • A virtual method In RadzenGrid that you call from BuildRenderTree to render the filter for column types you do not support.

That would allow the user to customize the filters without much effort on your side.

In the next version you will be able to do like this:

@page "/datagrid"

<RadzenExample Name="DataGrid">
@if (employees == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <RadzenGrid Data="@(employees.Where(e => e.TitleOfCourtesy == currentTOC))" 
                AllowFiltering="true" AllowPaging="true" AllowSorting="true" TItem="Employee" ColumnWidth="200px">
        <Columns>
            <RadzenGridColumn TItem="Employee" Property="ID" Title="ID" />
            <RadzenGridColumn TItem="Employee" Property="Name" Title="Name"/>
            <RadzenGridColumn TItem="Employee" Property="TitleOfCourtesy" Title="Title Of Courtesy">
                <FilterTemplate>
                    <RadzenDropDown @bind-Value="@currentTOC" TextProperty="Text" ValueProperty="Value" Style="width:100%"
                                    Data="@(Enum.GetValues(typeof(TitleOfCourtesy)).Cast<TitleOfCourtesy>().Select(t => new { Text = $"{t}", Value = t }))" />

                </FilterTemplate>
            </RadzenGridColumn>
        </Columns>
    </RadzenGrid>
}
</RadzenExample>

@code {
    public enum TitleOfCourtesy
    {
        Ms,
        Mr,
    }

    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public TitleOfCourtesy TitleOfCourtesy { get; set; }

    }

    IEnumerable<Employee> employees;
    TitleOfCourtesy currentTOC;

    protected override async Task OnInitializedAsync()
    {
        employees = await Task.FromResult(Enumerable.Range(0, 10).Select(i =>
            new Employee
            {
                ID = i,
                Name = $"Name{i}",
                TitleOfCourtesy = i < 5 ? TitleOfCourtesy.Mr : TitleOfCourtesy.Ms
            }));
    }
}

Thank you very much Vladimir!!!

Here is the demo with just released update of Radzen.Blazor:
https://blazor.radzen.com/datagrid-filter-template

Great!. I'm impatient to try it!

Vladimir, it looks like the hierarchical datagrids are broken:

https://blazor.radzen.com/master-detail-hierarchy

Look at the column filters. They are shifted one position to the left.

The filter template seems to work fine. However, in your example, you were binding to an external variable. What I really want is to create a derived class from RadzenGridColumn to handle all enum filtering automatically, even if I have to create the FilterTemplate using a RenderTreeBuilder. In order to do that, I want to filter by the column's FilterValue. As the FilterValue is of type object, it does not go well binding it to other controls with properties that are not of object type.In that case, I have to split the @bind-Value attribute in the two parts:

<FilterTemplate Context="data">
   <OptionalEnumField TEnum="BusinessPartnerStatus" Value="@((BusinessPartnerStatus?)data.FilterValue)" ValueChanged="@((args) => OnEnumFilterChanged(data, args))" ShowLabel="false" />
</FilterTemplate>

The OptionalEnumField component sets up a RadzenDropDown with the enum data.

And the implementation of OnEnumFilterChanged is:

protected async Task OnEnumFilterChanged(RadzenGridColumn<BusinessPartnerDto> column, BusinessPartnerStatus? value)
{
    var col = column as RadzenGridColumnEx<BusinessPartnerDto>;
    if (col != null) {
        col.SetFilterValue(value);
        col.Grid.Reload();
    }
}
</FilterTemplate>

I had to subclass the RadzenGridColumn to add the SetFilterValue method because assigning the FilterValue directly gives me this warning and it didn't work:

Component parameter 'FilterProperty' should not be set outside of its component

But having the SetFilterValue method in the RadzenGridColumn would be better:

public void SetFilterValue(object value)
{
    FilterValue = value;
}

Hierarchical grid will be fixed as for the filter template for columns this is the best we can offer for now.

Vladimir, the current filter templates are great as they're now. I was able to create my EnumGridColumn that does automatic filtering without any coding in the datagrid that uses them.

The only thing I missed was the SetFilterValue method in the RadzenGridColumn, for an usage that does not imply creating your column derived from RadzenGridColumn, but that is an easy thing to overcome.

Hello Vladimir,

the same project fails in Radzen Blazor 2.18.6 when you select an item from the RadzenDropdownDatagrid:

'''
[2020-12-17T15:02:57.176Z] Error: System.NotSupportedException: Unable to cast the type 'BlazorRadzenTests.Country' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ValidateAndAdjustCastTypes(TypeUsage toType, TypeUsage fromType, Type toClrType, Type fromClrType)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.CreateCastExpression(DbExpression source, Type toClrType, Type fromClrType)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.CastMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass41_0.<GetResults>b__1() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass41_0.<GetResults>b__0() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__31_0() at System.Data.Entity.Internal.LazyEnumerator1.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Radzen.DataBoundFormComponent1.get_View()
at Radzen.DropDownBase1.SelectItem(Object item, Boolean raiseChange) at Radzen.Blazor.RadzenDropDownDataGrid1.OnRowSelect(Object item)
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Radzen.Blazor.RadzenGrid`1.OnRowSelect(TItem item, Boolean raiseChange)
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
'''

I already told you that we can't help without a reproduction. Opening new threads or reviving old ones won't do any good.