EFCore DotNet 5 和自动映射器。地图虚拟馆藏

EFCore DotNet 5 & Automapper. Map virtual collections

首先,我是 Automapper 的新手,发现官方文档至少可以说很差。

我正在尝试用虚拟集合映射两个复杂实体,它们本身也需要映射

Map<IEnumerable<ComplexEntityDb>, IEnumerable<ComplexEntityVM>> 

在我需要映射的每一行中

Map<IEnumerable<EntityCollectionItemDb>, IEnumerable<EntityCollectionItemVM>>

类的一个非常简化的版本:

public class ComplexEntityDb
{
    public int Id;

    // Multiple properties (14) removed for brevity

    public virtual ICollection<EntityCollectionItemDb> CollectionDb { get; set; }
}

public class ComplexEntityVM
{
    public int Id;

    // Multiple properties (7) removed for brevity

    public virtual ICollection<EntityCollectionItemVM> CollectionDb { get; set; }
}


public class EntityCollectionItemDb
{
    public int Id;

    // Multiple properties (12) removed for brevity
}

public class EntityCollectionItemVM
{
    public int Id;

    // Multiple properties (6) removed for brevity
}

使用 AutoMapper 10.1.1 和 DI 扩展 8.1.1 在 dotnet 5 上使用 EF Core 5.04 执行此操作的正确方法是什么

我已经阅读了该站点上的数十篇文章,但似乎没有一种简单的方法可以做到这一点。

非常感谢更聪明的灵魂可以提供的任何帮助。

编辑:(摘自@dglozano 回答的评论部分)-

我正在使用映射配置文件 -

public class MappingProfile : Profile
{
    public MappingProfile() 
    {
        CreateMap<ComplexEntityDb, ComplexEntityVM>().ReverseMap();
        CreateMap<EntityCollectionItemDb, EntityCollectionItemVM>).ReverseMap(); 
    } 
} 

和 IMapper -

private readonly IMapper _mapper; 

public CustomService(IMapper mapper) 
{
    _mapper = mapper;
} 

并尝试 -

return _mapper.Map<IEnumerable<ComplexEntityDb>, IEnumerable<ComplexEntityVM>>(source); 

结果:EntityCollectionItemVM 集合为空。

你只需要定义每个元素类型的映射,如the documentation for Nested Mappings suggests. You have to tell Automapper how to map ComplexEntityDb -> ComplexEntityVM and how to map EntityCollectionItemDb -> EntityCollectionItemVM, and then all the mappings of collections of those items will automatically be supported.

所以在你的情况下,一个最小的例子是这样的:

using System;
using AutoMapper;
using System.Collections.Generic;

public class ComplexEntityDb
{
    public ComplexEntityDb(int id)
    {
        Id = id;
        var item1 = new EntityCollectionItemDb();
        var item2 = new EntityCollectionItemDb();
        item1.Id = id * 1000 + 1;
        item2.Id = id * 1000 + 2;
        CollectionDb = new List<EntityCollectionItemDb>{item1, item2, };
    }

    public int Id
    {
        get;
        set;
    }

    // Multiple properties (14) removed for brevity
    public ICollection<EntityCollectionItemDb> CollectionDb
    {
        get;
        set;
    }
}

public class ComplexEntityVM
{
    public int Id;
    // Multiple properties (7) removed for brevity
    public ICollection<EntityCollectionItemVM> CollectionDb
    {
        get;
        set;
    }
}

public class EntityCollectionItemDb
{
    public int Id;
// Multiple properties (12) removed for brevity
}

public class EntityCollectionItemVM
{
    public int Id;
// Multiple properties (6) removed for brevity
}

public class Program
{
    public static void Main()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<ComplexEntityDb, ComplexEntityVM>();
            cfg.CreateMap<EntityCollectionItemDb, EntityCollectionItemVM>();
        });
        var complexEntity1 = new ComplexEntityDb(1);
        var complexEntity2 = new ComplexEntityDb(2);
        var complexEntity3 = new ComplexEntityDb(3);
        var source = new List<ComplexEntityDb>{complexEntity1, complexEntity2, complexEntity3};
        var mapper = config.CreateMapper();
        var dest = mapper.Map<IEnumerable<ComplexEntityDb>, IEnumerable<ComplexEntityVM>>(source);
        
        foreach(var parentMapped in dest)
        {
            Console.WriteLine("Mapped parent Id {0}", parentMapped.Id);
            foreach(var childMapped in parentMapped.CollectionDb)
            {
                Console.WriteLine("  - Mapped child Id {0}", childMapped.Id);
            }
            Console.WriteLine();
        }
    }
}
Output:

Mapped parent Id 1
  - Mapped child Id 1001
  - Mapped child Id 1002

Mapped parent Id 2
  - Mapped child Id 2001
  - Mapped child Id 2002

Mapped parent Id 3
  - Mapped child Id 3001
  - Mapped child Id 3002

Try it out in this fiddle.

在更真实的场景中,它会是相同的想法,但我会创建一个 Profile(s) 来定义每个映射配置,然后使用注入的 IMapper 来执行映射.