设为首页 加入收藏

TOP

在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射(二)
2019-10-09 19:59:09 】 浏览:119
Tags:ASP.NET Core 项目 使用 AutoMapper 进行 实体 映射
get; set; } public string Category => CategoryCode == 1001 ? ".NET" : "杂谈"; public string ReleaseDate { get; set; } public short CommentCounts { get; set; } public virtual int Count { get; set; } }

  首先我们需要创建一个实体映射的配置类,需要继承于 AutoMapper 的 Profile 类,在无参构造函数中,我们就可以通过 CreateMap 方法去创建两个实体间的映射关系。

public class PostProfile : Profile
{
    /// <summary>
    /// ctor
    /// </summary>
    public PostProfile()
    {
        // 配置 mapping 规则
        //
        CreateMap<PostModel, PostViewModel>();
    }
}

  通过泛型的 CreateMap 方法就可以完成我们从 PostModel(PO) 到 PostViewModel(VO) 的实体映射。当然,因为 AutoMapper 默认是通过匹配字段名称和类型进行自动匹配,所以如果你进行转换的两个类的中的某些字段名称不一样,这里我们就需要进行手动的编写转换规则。

  就像在这个需要进行实体映射的示例代码中,PostViewModel 中的 CommentCounts 字段是根据 PostModel 中 CommentModel 集合的数据个数进行赋值的,所以这里我们就需要对这个字段的转换规则进行修改。

  在 AutoMapper 中,我们可以通过 ForMember 方法对映射规则做进一步的加工。这里我们需要指明 PostViewModel 的 CommentCounts 字段的值是通过对 PostModel 中的 Comments 信息进行求和从而获取到的,最终实现的转换代码如下所示。

public class PostProfile : Profile
{
    /// <summary>
    /// ctor
    /// </summary>
    public PostProfile()
    {
        // 配置 mapping 规则
        //
        CreateMap<PostModel, PostViewModel>()
            .ForMember(destination => destination.CommentCounts, source => source.MapFrom(i => i.Comments.Count()));
    }
}

  ForMember 方法不仅可以进行指定不同名称的字段进行转换,也可以通过编写规则实现字段类型的转换。例如这里 PO 中的 ReleaseDate 字段其实是 DateTime 类型的,我们需要通过编写规则将该字段对应到 VO 中 string 类型的 ReleaseDate 字段上,最终的实现代码如下所示。

public class PostProfile : Profile
{
    /// <summary>
    /// ctor
    /// </summary>
    public PostProfile()
    {
        // Config mapping rules
        //
        CreateMap<PostModel, PostViewModel>()
            .ForMember(destination => destination.CommentCounts, source => source.MapFrom(i => i.Comments.Count()))
            .ForMember(destination => destination.ReleaseDate, source => source.ConvertUsing(new DateTimeConverter()));
    }
}

public class DateTimeConverter : IValueConverter<DateTime, string>
{
    public string Convert(DateTime source, ResolutionContext context)
        => source.ToString("yyyy-MM-dd HH:mm:ss");
}

  这里很多人可能习惯将所有的实体映射规则都放到同一个 Profile 文件里面,因为这里采用是单体架构的项目,所以整个项目中会存在不同的模块,所以这里我是按照每个模块去创建对应的 Profile 文件。实际在 ingos-server 这个项目中的使用方式见下图所示。

   当我们创建好对应的映射规则后,因为我们是采用依赖注入的方式进行使用,所以这里我们就需要将我们的匹配规则注入到 IServiceCollection 中。从之前加载的程序集的 github readme 描述中可以看到,我们需要将配置好的 Profile 类通过 AddAutoMapper 这个扩展方法进行注入。

  因为我们在实际项目中可能存在多个自定义的 Profile 文件,而我们肯定是需要将这些自定义规则都注入到 IServiceCollection 中。所以我在 AddAutoMapper 这个方法的基础上创建了一个 AddAutoMapperProfiles 方法去注入我们的实体映射规则。

  通过 AutoMapper 的说明我们可以看出来,所有的自定义的 Profile 类都是需要继承于 AutoMapper 的 Profile 基类,所以这里我是采用反射的方式,通过获取到程序集中所有继承于 Profile 类的类文件进行批量的注入到 IServiceCollection 中,具体的实现代码如下所示。

/// <summary>
/// Automapper 映射规则配置扩展方法
/// </summary>
public static class AutoMapperExtension
{
    public static IServiceCollection AddAutoMapperProfiles(this IServiceCollection services)
    {
        // 从 appsettings.json 中获取包含配置规则的程序集信息
        string assemblies = ConfigurationManager.GetConfig("Assembly:Mapper");

        if (!string.IsNullOrEmpty(assemblies))
        {
            var profiles = new List<Type>();

            // 获取继承的 Profile 类型信息
            var parentType = typeof(Profile);

            foreach (var item in assemblies.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
            {
                //
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇EF Core 实现读写分离的最佳方案 下一篇.NET开发者必须学习.NET Core

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目