如何使用 AutoMapper 将枚举 ID 映射到基于枚举值的可查询投影?

How to use AutoMapper to map an Enum Id to a queryable projection based on Enum Values?

我正在尝试将枚举值 (Int16) 映射到 IQueryable 投影,以便使用枚举值的字符串表示形式而不是整数值进行数据库排序。

The approach I used was taken from .

枚举如下:

    public enum SafetyCategoryEnum : Int16 { High, Medium, Low }

查看下面我的 AutoMapper 映射:

config.CreateMap<SupplierContractEntity, SupplierContractEntityWrapper>()
                .ForMember(dest => dest.SafetyCategoryEnumId, 
                opt => { opt.MapFrom(EnumerableExpressionHelper.CreateEnumToStringExpression((SupplierContractEntity e) => e.SafetyCategoryEnumId)); })

SupplierContractEntity 是 EntityFramework 实体。

public class SupplierContractEntity : Entity
{
    //Other properties removed for brevity

    public Int16 SafetyCategoryEnumId { get; set; }    
}

SupplierContractEntityWrapper 是自定义业务对象:

public class SupplierContractEntityWrapper : EntityWrapper
{
    //Other properties removed for brevity

  public SafetyCategoryEnum? SafetyCategoryEnumId { get; set; }   
}

AutoMapper 中的表达式映射是相反的,这就是实体映射到业务对象的原因

CreateEnumToStringExpression 的实现:

public static class EnumerableExpressionHelper
{
    public static Expression<Func<TSource, string>> CreateEnumToStringExpression<TSource, TMember>(Expression<Func<TSource, TMember>> memberAccess, string defaultValue = "")
    {
        var type = typeof(SafetyCategoryEnum);
        var enumNames = Enum.GetNames(type);
        var enumValues = (Int16[])Enum.GetValues(type);
        var inner = (Expression)Expression.Constant(defaultValue);
        var parameter = memberAccess.Parameters[0];

        for (int i = 0; i < enumValues.Length; i++)
        {
            inner = Expression.Condition(
            Expression.Equal(memberAccess.Body, Expression.Constant(enumValues[i])),
            Expression.Constant(enumNames[i]), inner);
        }

        MyExpressionVisitor myExpressionVisitor = new MyExpressionVisitor();
        var expression = Expression.Lambda<Func<TSource, string>>(inner, parameter);
        myExpressionVisitor.Visit(expression);
        return expression;
    }
}

When performing a sort AutoMapper throws the following exception:

InvalidOperationException: Rewriting child expression from type 'System.Nullable`1[SafetyCategoryEnum]' to type 'System.String' is not allowed, because it would change the meaning of the operation. 
If this is intentional, override 'VisitUnary' and change it to allow this rewrite.

Is there any way around this type issue?

Any help would be greatly appreciated!

这适用于最新的 AM,但您需要将目标设为字符串。我认为您使用的不是最新版本,并且遇到了一个已经修复的错误。