您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页Web开发:使用Abp.AutoMapper进行实体映射的demo

Web开发:使用Abp.AutoMapper进行实体映射的demo

来源:五一七教育网

控制台程序为例,展示该demo

一、安装Nuget包

二、文件结构

三、AutoMapperProfile.cs(映射规则)

【基础demo】

【需求】Student 类的 Name 字段映射到 Teacher 类的 FullName 字段

using AutoMapper;

namespace ConsoleApp1
{
    public class AutoMapperProfile : Profile
    {
        public AutoMapperProfile()
        {
            CreateMap<Student, Teacher>()
                .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name));//配置不同名的字段映射
                                //其他字段:字段名称一样的自动映射

        }
    }
}

【解释和说明】

【映射检查】

        CreateMap<T,V>()中,允许入参控制是否进行映射检查

//映射规则:例如可以传入   CreateMap<源类,目标类>(MemberList.Source)
public enum MemberList
{
    Destination,//CreateMap不传参默认也是这种,【目标类有未被映射成员=>报错】
    Source,//【源类有未映射出去的成员=>报错】
    None//【源类,目标类是否被映射都不报错】
} 

【转换名称后映射】 

例如以下规则,就是Student(Name= "John")=>Teacher (FullName ="新名字John") 

.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => "新名字" + src.Name));

【双向映射】

CreateMap<Student, Teacher>().ReverseMap(); 

【多字段映射写法】 

CreateMap<Student, Teacher>()
                .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name))
                .ForMember(略)
                .ForMember(略);

 【字段的映射忽略】(避免报错)

假如public string Name { get; }  (没有set方法)会报错

解决方案一(封装方法判断此情况,自动跳过):

CreateMap<Student, Teacher>()
.IgnoreAllPropertiesWithAnInaccessibleSetter()
.IgnoreAllSourcePropertiesWithAnInaccessibleSetter(); // 忽略所有设置器不可访问的属性

解决方案二(不选择字段映射到FullName):

CreateMap<Student, Teacher>()
.ForMember(dest => dest.FullName, opt => opt.Ignore()); // 明确忽略特定属性

四、Model.cs(实体模型)


namespace ConsoleApp1
{
    public class Model
    {
    }
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public class Teacher
    {
        public int Id { get; set; }
        public string FullName { get; set; }
        public int Age { get; set; }
    }
}

五、Program.cs(程序入口)

using AutoMapper;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 配置规则
            var configuration = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<AutoMapperProfile>();
            });

            // 创建映射器
            IMapper mapper = configuration.CreateMapper();

            // 创建学生实体
            var student = new Student
            {
                Id = 1,
                Name = "小苏",
                Age = 20
            };

            // 映射成老师
            var teacher = mapper.Map<Teacher>(student);

            Console.WriteLine($"Teacher: Id={teacher.Id}, FullName={teacher.FullName}, Age={teacher.Age}");
            //输出:Teacher: Id=1, FullName=小苏, Age=20

        }
    }
}

六、ABP框架下实体映射的三种方式

方案一二(注入):

[Route("api/books")]
public class BookAppService : ApplicationService, IBookAppService
{
    private readonly IBookService _bookService;
    private readonly IObjectMapper _objectMapper;
    public BookAppService(
        IBookService bookService,
        IObjectMapper objectMapper
        )
    {

        _bookService = bookService;
        _objectMapper = objectMapper;
    }

    [Route("getbookbybll")]
    [HttpGet]
    public async Task<List<BookDto>> GetListByBLLAsync()
    {
        List<BookDto> list = await _bookService.GetBooks();//假设有一个服务可以获取List<BookDto>
        List<Book> test1 = ObjectMapper.Map<List<BookDto>,List<Book>>(list);//方案一,底层接口或者WebApi控制器继承ApplicationService,直接使用ObjectMapper(前提:应用层配置好映射关系CreateMap)
        List<Book> test2 = _objectMapper.Map<List<BookDto>,List<Book>>(list);//方案二,注入IObjectMapper使用(前提:应用层配置好映射关系CreateMap)
        return list;
    }

}

方案三:

var config = new MapperConfiguration(cfg => cfg.AddProfile<XXXXXXXXAutoMapperProfile>());//XXXXXXXXAutoMapperProfile 配置CreateMap规则
var list = config.CreateMapper().Map<List<源类>, List<目标类>>(list); //list是源类的列表数据

七、常见问题

1.ABP框架中忽略id映射

        ABP框架中Id不映射是如何做到的?
方案一:满足以下两个条件:
①目标类继承了DOEntity时,Id只允许get不允许set。

public class DOEntity : DOEntity<int>
{
    [Required]
    [Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public override int Id { get; protected set; }
}

②设置了忽略列,防止①带来报错

    .IgnoreAllPropertiesWithAnInaccessibleSetter()
    .IgnoreAllSourcePropertiesWithAnInaccessibleSetter()

方案二:直接用语法忽略

CreateMap<T, V>()
    .ForMember(dest => dest.Id, opt => opt.Ignore());

2.某个映射失败

请逐步排查:

①是否定义了CreateMap

        若定义了,CreateMap的映射检查(三选一)是否满足

②是否调用时写错了类名

3.映射语法报错

        以下两种写法是有区别的,CreateMap只创建实体即可,映射则要分清实体和列表。下面是调用的例子:

config.CreateMapper().Map<源类>, 目标类>(list);

config.CreateMapper().Map<List<源类>, List<目标类>>(list);

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务