如何在可查询投影期间使用 AutoMapper 将 int 映射到其枚举描述? [英] How to map an int to its enum description using AutoMapper during a queryable projection?

查看:25
本文介绍了如何在可查询投影期间使用 AutoMapper 将 int 映射到其枚举描述?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是获取其描述属性的枚举扩展方法.

Here is the enum extension method to get its description attribute.

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

这里是源对象:

public class Account {
    public int AccountId {get;set;}
    public int AccountStatusId {get;set;}
}

这里是枚举:

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

这里是目标对象:

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

这是我的映射尝试(使用最新的非静态自动映射器版本).请记住,这是在 EF 可查询投影期间.

Here is my attempt to map (using the latest non-static automapper version). Remember this is during an EF queryable projection.

_config = new MapperConfiguration(cfg => cfg.CreateMap<Account, GetAccountsResponse>()
    .ForMember(dest => dest.Status,
        opts => opts.MapFrom(src => ((AccountStatus) src.AccountStatusId).GetDescription())));

这是查询是 IQueryable 的投影:

Here is the projection where query is an IQueryable<Account>:

query.ProjectToList<GetAccountResponse>(_config);

这是我得到的例外:

无法将其解析为可查询表达式

Can't resolve this to Queryable Expression

推荐答案

如果您查看 MapFrom 方法的签名,您会注意到其中一个重载采用 Expression<Func<TSource 类型的参数, TMember>>.

If you check out the signature of the MapFrom method, you'll notice that one of the overloads takes a parameter of type Expression<Func<TSource, TMember>>.

这表明您可以编写一个从三元表达式构建表达式树的方法,该方法可以将枚举的任何可能值转换为其适当的字符串.AutoMapper 然后会通过 LINQ 将其转换为适当的 SQL 表达式.

This suggests that you could write a method which builds an expression tree from ternary expressions that can convert any possible value of your enum to its appropriate string. AutoMapper would then convert this into the appropriate SQL expression via LINQ.

这是一个仅使用枚举名称本身的示例:您应该能够直接对其进行调整以使用您的描述:

Here's an example which just uses the Enum names themselves: you should be able to adapt it straightforwardly to use your Descriptions:

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

您可以按如下方式使用它:

You would use it as follows:

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

这篇关于如何在可查询投影期间使用 AutoMapper 将 int 映射到其枚举描述?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆