System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

.Net 6 not support for calculated field

Open sandunangelo opened this issue 3 years ago • 7 comments

This nuget package version 1.2.14 was working great with .Net Core 2.0, and my project is now upgraded to .Net 6.

My data collection has a custom DTO including a string MemberTypeText field which returns the text version of the same class enum field of MemberType. Previously OrderBy() method works for MemberTypeText but now the expression crashes with the error ...could not be translated. either rewrite the query in a form that can be translated,... Below is my C# statement.

var list = await source.OrderBy("MemberTypeText").ToListAsync();

TIA!

sandunangelo avatar Feb 21 '22 06:02 sandunangelo

What does source.ElementType return? source.GetType()?

Are you calling any other LINQ methods to create source?

Just to confirm, MemberTypeText is a field, not a property?

zspitz avatar Feb 21 '22 09:02 zspitz

Sorry for the incompleteness,

source is a generic list collection of DTO, ex: List<MemberDto> MemberTypeText is a property in the DTO, so when comes to LINQ world, we can called it a field to query.

public class MemberDto{
        // other fields/properties also in the class

        public MembershipType MembershipType { get; set; } = MembershipType.Simple;

        public string MembershipTypeText
        {
            get
            {
                return MembershipType.GetDisplayName(); // refer below extension method
            }
        }
}

Extension method to get display text for an enum value

public static string GetDisplayName(this Enum value)
{
    var attribute = value.GetAttribute<DisplayAttribute>();
    return attribute == null ? value.ToString() : attribute.Name;
}

sandunangelo avatar Feb 22 '22 04:02 sandunangelo

The following:

using System.ComponentModel.DataAnnotations;
using System.Linq.Dynamic.Core;
using System.Reflection;

IQueryable source = new List<MemberDto>().AsQueryable();
source = source.OrderBy("MembershipTypeText");
Console.WriteLine(
    source.Expression
);

public enum MembershipType {
    Simple,
    Complex
}

public class MemberDto {
    public MembershipType MembershipType { get; set; } = MembershipType.Simple;
    public string MembershipTypeText => MembershipType.GetDisplayName();
}

public static class Extensions {
    public static string? GetDisplayName(this Enum value) =>
        value.GetType().GetCustomAttribute<DisplayAttribute>() switch {
            null => value.ToString(),
            var attribute => attribute.Name
        };
}

works just fine and prints out:

System.Collections.Generic.List`1[MemberDto].OrderBy(Param_0 => Param_0.MembershipTypeText)

Do you have any thoughts on why your code might be acting differently?

zspitz avatar Feb 22 '22 07:02 zspitz

@sandunangelo Did you try the proposed code change from Zev Spitz?

StefH avatar Apr 17 '22 19:04 StefH

Sorry guys, could not attend to this issue to check the given solution either, had to switch the work context. Will update here when I switched back.

sandunangelo avatar Apr 18 '22 04:04 sandunangelo

@sandunangelo Did you already have time to investigate?

StefH avatar Jun 01 '22 16:06 StefH

@sandunangelo Did you already have time to investigate?

StefH avatar Aug 02 '22 19:08 StefH

@sandunangelo Did you already have time to investigate?

StefH avatar Feb 04 '23 17:02 StefH