【问题标题】:AutoMapper c# runtime mapping depending on an object propertyAutoMapper c# 运行时映射取决于对象属性
【发布时间】:2019-06-03 16:31:27
【问题描述】:

我想知道,如何使用 AutoMapper 将一个 Dto 映射到多个实体。

请解释一下。

我有一个 Dto,用一个枚举来描述它的类型(以避免有多个 dto)

根据该枚举(此处为 RelationType),我想将其映射到正确的模型(实体,无论如何,它是我在数据库中使用的另一个对象)。

public class BCardDto : IMappedDto
{
    public long Id { get; set; }

    public BCardRelationType RelationType { get; set; }
    public long RelationId { get; set; }
}

这是我的模型库:

public class BCardModel : IMappedDto
{
    public long Id { get; set; }
}

这里是派生模型:

public class CardBCardModel : BCardModel
{
    // ormlite, ignore that
    [Reference]
    public CardModel Card { get; set; }

    [ForeignKey(typeof(CardModel), ForeignKeyName = "fk_bcard_card")]
    public long RelationId { get; set; }
}

如何根据我给出的枚举将我的 Dto 映射到正确的模型? (我不想到处使用 Mapper.Map 但我想让 mapper 做运行时映射工作)

这是我为模型做的 -> Dto

        cfg.CreateMap<CardBCardModel, BCardDto>()
            .ForMember(s => s.RelationType, expression => expression.UseValue(BCardRelationType.Card))
            .IncludeBase<BCardModel, BCardDto>();

如果我做错了什么,请告诉我并解释原因:)

提前致谢, 布洛瓦。

【问题讨论】:

  • 看起来有人遇到了同样的问题here 不知道这是否是正确的解决方案
  • 那么您要映射到的另一个模型在哪里?

标签: c# automapper


【解决方案1】:

假设您有一个设置,其中有一个基类和两个派生基类的类:

public class ModelBase
{
    public string Name { get; set; }
}

public class ModelOne : ModelBase { }

public class ModelTwo : ModelBase { }

假设您有一个带有如下枚举的 DTO:

public class ModelDto
{
    public string Name { get; set; }
    public ModelType ModelType { get; set; }
}

public enum ModelType
{
    One = 1,
    Two = 2
}

所以现在的任务是:如何根据ModelDto.ModelType 属性中的值将ModelDto 映射到ModelOneModelTwo

方法如下:

Mapper.Initialize(cfg => cfg.CreateMap<ModelDto, ModelBase>().ConstructUsing(x => 
{
    switch (x.ModelType)
    {
        case ModelType.One:
            return new ModelOne { Name = x.Name };
        case ModelType.Two:
            return new ModelTwo { Name = x.Name };
        default:
            throw new InvalidOperationException("Unknown ModelType...");
    }
}));

用法

var dto1 = new ModelDto { ModelType = ModelType.One, Name = "ModelOne" };
var dto2 = new ModelDto { ModelType = ModelType.Two, Name = "ModelTwo" };

var one = Mapper.Map<ModelBase>(dto1);
var two = Mapper.Map<ModelBase>(dto2);

【讨论】:

  • 感谢您的回答,这就是我想做的:)!但我认为我会使用 AutoMapper 而不是 return new (我知道你用过它)
【解决方案2】:

另一种映射方式是使用动态:

public class PersonDto
{
    public string Name { get; set; }
}

public class StudentDto : PersonDto
{
    public int studentNumber { get; set; }
}

public class EmployeDto  : PersonDto
{
    public string EmployeId { get; set; }
}

public class Person
{
    public string Name { get; set; }
}

public class Student : Person
{
    public int StudentNumber { get; set; }
}

public class Employe : Person
{
    public string EmployeId { get; set; }
}

使用以下方法创建地图:

Mapper.CreateMap<StudentDto, Student>();
Mapper.CreateMap<EmployeDto, Employe>();

通过以下方式进行映射:

try
{
    var student = MapPerson((dynamic) studentDto);
    var employe = MapPerson((dynamic) employeDto);
}
catch
{
    throw new InvalidOperationException("Unknown ModelType...");
}

并定义两个方法

public static Student MapPerson(StudentDto studentDto)
{
    return Mapper.Map<StudentDto, Student>(studentDto);
}

public static Employe MapPerson(EmployeDto employeDto)
{
    return Mapper.Map<EmployeDto, Employe>(employeDto);
}

好处是不需要key,避免switch语句

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    相关资源
    最近更新 更多