c# - 使用 AutoMapper 将描述枚举为字符串

Ser*_*gio 5 c# reflection enums projection automapper

我正在尝试从我的Order模型投影到我的OrderDTO模型。Order有一个枚举。问题是,如果我尝试从枚举中获取Description属性,则投影不起作用。这是我的代码:

在我的AutoMapper.cs 中使用以下配置:

cfg.CreateMap<Order, OrderDTO>().ForMember(
    dest => dest.Status,
    opt => opt.MapFrom(src => src.Status.ToString())
);
Run Code Online (Sandbox Code Playgroud)

投影有效,但我得到一个像这样的OrderDTO对象:

 - Id: 1
 - OrderLines: List<OrderLines>
 - Sent //I want "Delivered"!
Run Code Online (Sandbox Code Playgroud)

我不希望Status属性为“已发送”,我希望将其作为其关联的描述属性,在本例中为“已交付”。

我尝试了两种解决方案,但都没有奏效:

  1. 使用ResolveUsing AutoMapper功能解释这里,但是,因为它规定在这里

投影不支持 ResolveUsing,有关支持的操作,请参阅 LINQ 投影上的 wiki。

  1. 使用静态方法通过反射返回String 中的Description属性。

    cfg.CreateMap<Order, OrderDTO>().ForMember(
        dest => dest.Status,
        opt => opt.MapFrom(src => EnumHelper<OrderStatus>.GetEnumDescription(src.Status.ToString()))
    );
    
    Run Code Online (Sandbox Code Playgroud)

但这给了我以下错误:

LINQ to Entities 无法识别“System.String GetEnumDescription(System.String)”方法,并且此方法无法转换为存储表达式。

那么,我怎样才能做到这一点?

Joh*_* Wu 2

您可以添加一个像这样的扩展方法(借用了这篇文章的逻辑):

\n\n
public static class ExtensionMethods\n{\n    static public string GetDescription(this OrderStatus This)\n    {\n        var type = typeof(OrderStatus);\n        var memInfo = type.GetMember(This.ToString());\n        var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);\n        return ((DescriptionAttribute)attributes[0]).Description;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在您的地图中访问它:

\n\n
cfg => \n{\n    cfg.CreateMap<Order, OrderDTO>()\n    .ForMember\n    (\n        dest => dest.Status,\n        opt => opt.MapFrom\n        (\n            src => src.Status.GetDescription()\n        )\n    );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会产生您所要求的结果:

\n\n
Console.WriteLine(dto.Status);  //"Delivered", not "sent"\n
Run Code Online (Sandbox Code Playgroud)\n\n

查看 DotNetFiddle 上的工作示例

\n\n

Edit1:Don\xe2\x80\x99t 认为您可以向 LINQ to 实体添加类似的本地查找功能。它仅适用于 LINQ to 对象。您应该追求的解决方案也许是数据库中的域表,它允许您连接到它并返回所需的列,这样您就不必使用 AutoMapper 执行任何操作。

\n