2

Açıklama özniteliğini almak için enum uzantı yöntemini burada bulabilirsiniz.Yüklenecek bir projeksiyon sırasında AutoMapper kullanarak bir enum açıklamasına nasıl eşlenir?

İşte
public class GetAccountResponse { 
    public int AccountId {get;set;} 
    public string Status {get;set;} 
} 

benim girişimi: Burada

public enum AccountStatus { 
    [Description("N/A")] 
    None, 
    [Description("OPEN")] 
    Open, 
    [Description("CLOSED")] 
    Closed, 
    [Description("BAD CREDIT") 
    Problem 
} 

hedef nesnesidir: Burada
public class Account { 
    public int AccountId {get;set;} 
    public int AccountStatusId {get;set;} 
} 

enum: İşte
public static string GetDescription(this Enum enumeration) 
{ 
    if (enumeration == null) 
     throw new ArgumentNullException(); 

    var value = enumeration.ToString(); 
    var type = enumeration.GetType(); 
    var descriptionAttribute = 
     (DescriptionAttribute[]) type.GetField(value).GetCustomAttributes(typeof (DescriptionAttribute), false); 

    return descriptionAttribute.Length > 0 ? descriptionAttribute[0].Description : value; 
} 

kaynak nesnesidir harita (en son non-statik automappe kullanarak r sürümü). Bunun bir EF gecikmeli projeksiyon sırasında olduğunu unutmayın. İşte
_config = new MapperConfiguration(cfg => cfg.CreateMap<Account, GetAccountsResponse>() 
    .ForMember(dest => dest.Status, 
     opts => opts.MapFrom(src => ((AccountStatus) src.AccountStatusId).GetDescription()))); 

sorgu nerede projeksiyonu bir IQueryable<Account>:

query.ProjectToList<GetAccountResponse>(_config); 

Bu durum alıyorum:

bu Expression queryable için çözülemiyor

cevap

1

MapFrom yönteminin imzasını kontrol ederseniz, aşırı yüklenmelerden birinin Expression<Func<TSource, TMember>> türünde bir parametre aldığını fark et.

Bu, enum öğenizin olası değerini uygun dizeye dönüştürebilen üçlü ifadelerden bir ifade ağacı oluşturan bir yöntem yazabileceğinizi gösterir. AutoMapper daha sonra bunu LINQ ile uygun SQL ifadesine dönüştürür. İşte

sadece numaralandırma adları kendilerini kullanan bir örnek şu şekildedir:

public static class EnumerableExpressionHelper 
{ 
    public static Expression<Func<TSource, String>> CreateEnumToStringExpression<TSource, TMember>(
     Expression<Func<TSource, TMember>> memberAccess, string defaultValue = "") 
    { 
     var type = typeof(TMember); 
     if (!type.IsEnum) 
     { 
      throw new InvalidOperationException("TMember must be an Enum type"); 
     } 

     var enumNames = Enum.GetNames(type); 
     var enumValues = (TMember[])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); 
     } 

     var expression = Expression.Lambda<Func<TSource,String>>(inner, parameter); 

     return expression; 
    } 
} 

Sen bunu kullanan: Eğer Açıklamaları kullanmak delikanlı adapte gerekir

CreateMap<Entry, EntryListItem>() 
      .ForMember(e => e.ReviewStatus, 
       c => c.MapFrom(EnumerableExpressionHelper.CreateEnumToStringExpression((Entry e) => e.ReviewStatus)))