为什么Automapper会自动将Driver.Name映射到DriverName

时间:2017-06-11 15:33:03

标签: c# automapper automapper-6

我有以下课程:

public partial class ScheduledDeduction
{
    public int ID { get; set; }

    public int DriverId { get; set; }

    public string Description { get; set; }

    public DateTime DateTime { get; set; }

    public decimal Amount { get; set; }

    public virtual Driver Driver { get; set; }
}

public partial class Driver
{

    public int ID { get; set; }

    public int CompanyId { get; set; }

    public string Name { get; set; }

和View Model类:

public abstract class ScheduledDeductionDetailVM
{
    public int ID { get; set; }

    [Display(Name = "Driver Name")]
    public string DriverName { get; set; }

    public string Description { get; set; }

    [Display(Name = "Date")]
    [DisplayFormat(DataFormatString = "{0:d}")]
    public System.DateTime DateTime { get; set; }

    [Display(Name = "Amount")]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public decimal Amount { get; set; }
}

我有以下Automapper规则:

CreateMap<Infrastructure.Asset.ScheduledDeduction, ViewModels.ScheduledDeductionDetailVM>();

并尝试使用:

ScheduledDeduction scheduledDeduction = db.ScheduledDeductions.Find(id);
ScheduledDeductionDetailVM model = mapper.Map<ScheduledDeductionDetailVM>(scheduledDeduction);

它有效!为什么? ScheduledDeductionDetailVM具有属性DriverName,可以从ScheduledDeduction.Driver.Name获取,它从未描述过。但它的映射正确......

2 个答案:

答案 0 :(得分:4)

这是框架的一个特色。

根据documentation about Flattening

  

对象 - 对象映射的一个常见用法是采用复杂的方法   对象模型并将其展平为更简单的模型。

     

...

     

在AutoMapper中配置源/目标类型对时,   配置程序尝试匹配源上的属性和方法   键入目标类型的属性。如果对于任何财产   目标类型以“获取”为前缀的属性,方法或方法   在源类型上不存在,AutoMapper会分割目标   成员名称为单个单词(通过PascalCase约定)。

答案 1 :(得分:2)

Automapper使用许多不同的conventions,这种行为也是不同约定的一部分。在关于Flattening的页面上,声明

  

如果目标上的任何属性键入属性,方法或a   源类型上不存在前缀为“Get”的方法,   AutoMapper将目标成员名称拆分为单个单词   (通过PascalCase惯例)。

但如果你这样做:

var config = new MapperConfiguration(cfg => {
    cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention();                
    cfg.CreateMap<ScheduledDeduction, ScheduledDeductionDetailVM>();
});

将不再是这种情况,因为您将目标成员命名约定从PascalCase更改为LowerUnderscore。

或者如果你这样做:

var config = new MapperConfiguration(cfg => {
    var profile = (Profile)cfg;
    profile.DefaultMemberConfig.MemberMappers.Clear();
    cfg.CreateMap<ScheduledDeduction, ScheduledDeductionDetailVM>();
});

它还会破坏您观察到的行为,因为您删除了成员命名约定。