8

我的问题是从数据库返回的 Linq2Sql 对象中为 Viewmodel 补水。我们已经在一些领域做到了这一点,并为它设计了一个很好的分层模式,但最新的项目要求使用一些枚举,这引起了各方的头痛。目前我们从数据库中拉回然后使用 Automapper 水合(或展平)到我们的视图模型中,但是模型中的枚举似乎会导致 Automapper 出现问题。我已经尝试创建足以满足我所有其他映射要求的自定义解析器,但在这种情况下它不起作用。

代码示例如下所示:

public class CustomerBillingTabView{
    public string PaymentMethod {get; set;}
    ...other details
}

public class BillingViewModel{
    public PaymentMethodType PaymentMethod {get; set;}
    ...other details
}

public enum PaymentMethodType {
    Invoice, DirectDebit, CreditCard, Other
}

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        if (string.IsNullOrWhiteSpace(source.PaymentMethod))
        {
            source.PaymentMethod = source.PaymentMethod.Replace(" ", "");
            return (PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), source.PaymentMethod, true);
        }

        return PaymentMethodType.Other;
    }
}

        CreateMap<CustomerBillingTabView, CustomerBillingViewModel>()
        .ForMember(c => c.CollectionMethod, opt => opt.ResolveUsing<PaymentMethodTypeResolver>())

我收到以下错误

[ArgumentException: Type provided must be an Enum.
Parameter name: enumType]
   System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) +9626766
   System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) +80
   AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) +231
   AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) +720

我想在我们所有的映射操作中坚持使用 Automapper,但我看到很多人说它不做这种类型的映射,所以我开始怀疑我是否用错了方法?此外,我已经看到了一些关于 ValueInjecter 的提及——这是 Automapper 的替代品,还是仅堵住 Automapper 中的孔以对模型进行水合并使用 Automapper 进行展平是否有用?

是的,我可以只在我的 ViewModel 中使用一个字符串,但我不喜欢魔术字符串,并且这个特殊的项目被助手用来在许多地方执行一些逻辑。

4

2 回答 2

10

这是 AutoMapper 文档的问题。如果您下载 AutoMapper 源代码,那里有示例。您想要的代码如下所示:

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        string paymentMethod = source.Context.SourceValue as string;

        if (string.IsNullOrWhiteSpace(paymentMethod))
        {
            paymentMethod  = paymentMethod.Replace(" ", "");
            return source.New((PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), paymentMethod, true));
        }

        return source.New(PaymentMethodType.Other);
    }
}
于 2010-09-20T18:59:14.630 回答
5

这是ValueInjecter的解决方案:既然您已经解决了问题,我将向您指出类似的问题:

AutoMapper 字符串到枚举描述

在这个问题中,要求不仅仅是从字符串到枚举,但它也包括这种转换

关于 ValueInjecter 是一种替代方案:是的,它的内容更通用,无需为所需的每一件小事进行配置,并构建您可以想象的任何约定

于 2010-09-24T19:26:49.267 回答