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

时间:2017-08-18 18:08:08

标签: entity-framework enums automapper iqueryable

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

  

我使用的方法取自here

Enum如下:

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

请参阅下面的我的AutoMapper映射:

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

    public Int16 SafetyCategoryEnumId { get; set; }    
}

SupplierContractEntity是EntityFramework Entity。

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

  public SafetyCategoryEnum? SafetyCategoryEnumId { get; set; }   
}

SupplierContractEntityWrapper是一个自定义业务对象:

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;
    }
}

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

CreateEnumToStringExpression的实现:

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.
  

执行排序时,AutoMapper会抛出以下异常:

[self addChild:childNode];
childNode = self.zPosition - 1;
  

有没有解决此类问题的方法?

     

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

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