首页 > 解决方案 > 在 AutoMapper 投影中创建 Linq 表达式以将 int 转换为枚举名称

问题描述

我想简化我当前的视图模型映射。我目前使用 AutomapperProjectTo创建我的视图模型,然后调用 post mapping 方法StatusDescription string从枚举中填充一个属性,该Status枚举的值在int视图模型类的另一个属性中,StatusId.

我找到了另一个答案,但我无法让它工作,并且由于我普遍缺乏表达经验,我很难理解它到底在做什么。

作为参考,这里是表达式方法(注意我必须注释掉 defaultValue 参数,因为我得到一个错误An expression tree may not contain a call or invocation that uses optional arguments

public static Expression<Func<TSource, String>> CreateEnumToStringExpression<TSource, TMember>(
    Expression<Func<TSource, TMember>> memberAccess)//,string defaultValue = ""
{
    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;
}

我这样称呼它:

.ForMember(dest => dest.Status, option =>
    option.MapFrom(src =>
        EnumHelper.ExpressionHelper
        .CreateEnumToStringExpression((ShippingContainerHeader s) => s.StatusId)
    ))

运行此程序时遇到的错误是: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression..

A.)我想我说错了也许?我不应该srcMapFrom方法调用中使用对的引用来将实际值传递StatusId给表达式方法吗?

B.) 表达式生成方法似乎存在问题,因为它会产生ToString()错误。该方法中没有显式.ToString()调用,但它必须以某种方式隐含。

CreateEnumToStringExpressionC.) 理解代码:除了parameter变量是什么和最终的expression变量表达式语句之外,我可以遵循方法中的所有代码。此外,我对泛型类型感到困惑......有很多泛型类型,并且从链接示例中对方法的调用没有明确定义它们中的任何一个。

Expression<Func<TSource, String>>很确定TSource输入是int. String是输出,这将是枚举名称。

CreateEnumToStringExpression<TSource, TMember>Expression<Func<TSource, TMember>> memberAccessTSource再次是,intTMember枚举类类型。

但是在调用方法的时候是不是就不用显式调用这些了?就像是:CreateEnumToStringExpression<int, StatusesEnum>(new Expression<Func<int, ShippingContainerHeader>> { s => s.StatusId })

标签: c#genericsentity-framework-6automapperlinq-expressions

解决方案


推荐阅读