2017-08-18 4 views
0

J'essaye de mapper une valeur Enum (Int16) à une projection IQueryable de sorte que la représentation de chaîne de la valeur Enum soit utilisée plutôt que la valeur entière pour le tri de base de données.Comment utiliser AutoMapper pour mapper un Id Enum à une projection interrogeable basée sur des valeurs Enum?

L'approche que j'ai utilisée provient de here.

Enum comme suit:

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

Voir ma cartographie AutoMapper ci-dessous:

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

SupplierContractEntity est l'entité EntityFramework.

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

    public Int16 SafetyCategoryEnumId { get; set; }  
} 

SupplierContractEntityWrapper est un objet métier personnalisé:

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

    public SafetyCategoryEnum? SafetyCategoryEnumId { get; set; } 
} 

cartographie d'expression est inversée dans AutoMapper ce qui explique pourquoi les cartes entité à l'objet métier

de mise en œuvre de 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; 
    } 
} 

Lorsque vous effectuez une sorte AutoMapper jette l'exception suivante:

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. 

Yat-il un moyen de contourner ce problème de type?

Toute aide serait grandement appréciée!

Répondre

0

Cela fonctionne pour moi avec le dernier AM, mais vous devez faire la destination une chaîne. Je pense que vous n'êtes pas sur la dernière version et que vous avez atteint un bug déjà corrigé.

+0

Merci Lucian. Le problème était que la destination n'était pas une chaîne. – sjr