c# - 在 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.)我想我说错了也许?我不应该src
在MapFrom
方法调用中使用对的引用来将实际值传递StatusId
给表达式方法吗?
B.) 表达式生成方法似乎存在问题,因为它会产生ToString()
错误。该方法中没有显式.ToString()
调用,但它必须以某种方式隐含。
CreateEnumToStringExpression
C.) 理解代码:除了parameter
变量是什么和最终的expression
变量表达式语句之外,我可以遵循方法中的所有代码。此外,我对泛型类型感到困惑......有很多泛型类型,并且从链接示例中对方法的调用没有明确定义它们中的任何一个。
我Expression<Func<TSource, String>>
很确定TSource
输入是int
. String
是输出,这将是枚举名称。
CreateEnumToStringExpression<TSource, TMember>
和Expression<Func<TSource, TMember>> memberAccess
:TSource
再次是,int
是TMember
枚举类类型。
但是在调用方法的时候是不是就不用显式调用这些了?就像是:CreateEnumToStringExpression<int, StatusesEnum>(new Expression<Func<int, ShippingContainerHeader>> { s => s.StatusId })