The LINQ expression could not be translated for base property

后端 未结 1 1376
栀梦
栀梦 2020-12-21 05:34

I have custom OrderBy implementation, it only works for types without inheritance, if I want order by field from base type I got The LINQ expression could not be translated

相关标签:
1条回答
  • 2020-12-21 05:49

    I've seen something like this before. The only difference between compiler generated and manual expression is the ReflectedType property of the PropertyInfo - in compiler generated code it's the same as DeclaringType, which in this case is the base class, while in the PropertyInfo obtained via type.GetProperty it is the derived type used to obtain it.

    For some unknown reason (probably a bug) this is confusing EF Core. The workaround is to change the code as follows:

    var property = type.GetProperty(orderByProperty);
    if (property.DeclaringType != property.ReflectedType)
        property = property.DeclaringType.GetProperty(property.Name);
    

    or use a helper method like this

    static PropertyInfo GetProperty(Type type, string name)
    {
        for (; type != null; type = type.BaseType)
        {
            var property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            if (property != null) return property;
        }
        return null;
    }
    

    In order to support nested properties, I would add the following helpers

    static Expression Property(Expression target, string name) =>
        name.Split('.').Aggregate(target, SimpleProperty);
    
    static Expression SimpleProperty(Expression target, string name) =>
        Expression.MakeMemberAccess(target, GetProperty(target.Type, name));
    

    and then use

    var propertyAccess = Property(param, orderByProperty);
    

    and

    new Type[] { type, orderByExpression.ReturnType },
    

    inside the method in question.

    0 讨论(0)
提交回复
热议问题