我正在尝试从我的订单模型投影到我的OrderDTO模型.订单有一个枚举.问题是如果我尝试从Enum获取Description属性,则投影不起作用.这是我的代码:
> OrderStatus.cs:
public enum OrderStatus {
[Description("Paid")]
Paid,
[Description("Processing")]
InProcess,
[Description("Delivered")]
Sent
}
> Order.cs:
public class Order {
public int Id { get; set; }
public List<OrderLine> OrderLines { get; set; }
public OrderStatus Status { get; set; }
}
> OrderDTO.cs:
public class OrderDTO {
public int Id { get; set; }
public List<OrderLineDTO> OrderLines { get; set; }
public string Status { get; set; }
}
在我的AutoMapper.cs中使用以下配置:
cfg.CreateMap<Order, OrderDTO>().ForMember(
dest => dest.Status,
opt => opt.MapFrom(src => src.Status.ToString())
);
投影工作,但我得到一个这样的OrderDTO对象:
- Id: 1
- OrderLines: List<OrderLines>
- Sent //I want "Delivered"!
我不希望Status属性为“已发送”,我希望它作为其关联的Description属性,在本例中为“Delivered”.
我尝试了两种解决方案,但没有一种方法有效:
>使用Resolve使用AutoMapper函数,如here所述,但是,如07100所述:
ResolveUsing is not supported for projections, see the wiki on LINQ projections for supported operations.
>使用静态方法通过Reflection返回String中的Description属性.
cfg.CreateMap<Order, OrderDTO>().ForMember(
dest => dest.Status,
opt => opt.MapFrom(src => EnumHelper<OrderStatus>.GetEnumDescription(src.Status.ToString()))
);
但这给了我以下错误:
LINQ to Entities does not recognize the method ‘System.String
GetEnumDescription(System.String)’ method, and this method cannot be
translated into a store expression.
然后,我该怎样才能做到这一点?
最佳答案 您可以添加像这样的扩展方法(借用
this post中的逻辑):
public static class ExtensionMethods
{
static public string GetDescription(this OrderStatus This)
{
var type = typeof(OrderStatus);
var memInfo = type.GetMember(This.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
return ((DescriptionAttribute)attributes[0]).Description;
}
}
然后在地图中访问它:
cfg =>
{
cfg.CreateMap<Order, OrderDTO>()
.ForMember
(
dest => dest.Status,
opt => opt.MapFrom
(
src => src.Status.GetDescription()
)
);
}
这导致您要求的:
Console.WriteLine(dto.Status); //"Delivered", not "sent"
See a working example on DotNetFiddle
Edit1:不要认为你可以向LINQ实体添加像这样的本地查找功能.它只适用于LINQ对象.您应该追求的解决方案可能是数据库中的域表,允许您加入它并返回您想要的列,这样您就不必对AutoMapper执行任何操作.