繁体   English   中英

AutoMapper:一对多->多对多

[英]AutoMapper: One-to-many -> Many-to-many

我是AutoMapper的新手。 我也很难配置AutoMapper在能够映射UserViewModel具有多个TagViewModel成许多一对多关系( RecipeEntity <-> TagEntity这是所需要的实体框架的核心,其中UserAndTagEntity是接合表。

数据对象:

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

    public virtual ICollection<UserAndTagEntity> UserAndTags { get; set; } = new List<UserAndTagEntity>();
}

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

    public virtual ICollection<UserAndTagEntity> UserAndTags { get; set; } = new List<UserAndTagEntity>();
}

public class UserAndTagEntity
{
    public int Id { get; set; }
    public virtual UserEntity User { get; set; }
    public virtual TagEntity Tag { get; set; }
}

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

    public IList<TagViewModel> Tags { get; set; }
}

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

测试例:

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<UserEntity, UserViewModel>()
        .ForMember(
            dto => dto.Tags,
            opt => opt.MapFrom(x => x.UserAndTags.Select(y => y.Tag)));

    cfg.CreateMap<UserViewModel, UserEntity>()
        .ForMember(
            dto => dto.UserAndTags,
            opt => opt.MapFrom(x => x.Tags))
        .AfterMap((model, entity) =>
        {
            foreach (var entityUserAndTag in entity.UserAndTags)
            {
                entityUserAndTag.User = entity;
            }
        });

    cfg.CreateMap<TagViewModel, UserAndTagEntity>();
});

var user = new UserViewModel()
{
    Name = "User",
    Tags = new List<TagViewModel>
    {
        new TagViewModel {Name = "Tag 1"},
        new TagViewModel {Name = "Tag 2"},
        new TagViewModel {Name = "Tag 3"},
        new TagViewModel {Name = "Tag 4"},
    }
};

IMapper mapper = config.CreateMapper();

var map = mapper.Map<UserViewModel, UserEntity>(user);

此工程部分-我的问题是, TagUserAndTagEntity为空。

使用以下配置可以实现从UserViewModelUserEntity的映射:

CreateMap<UserViewModel, UserEntity>()
    // (1)
    .ForMember(entity => entity.UserAndTags, opt => opt.MapFrom(model => model.Tags))
    // (5)
    .AfterMap((model, entity) =>
    {
        foreach (var entityUserAndTag in entity.UserAndTags)
        {
            entityUserAndTag.User = entity;
        }
    });

// (2)
CreateMap<TagViewModel, UserAndTagEntity>()
    // (3)
    .ForMember(entity => entity.Tag, opt => opt.MapFrom(model => model));

// (4)
CreateMap<TagViewModel, TagEntity>();

说明:

需要线(1),因为目标和源属性名称不匹配,所以我们只是告诉AutoMapper映射Tags的财产UserViewModelUserAndTags的财产UserEntity

请注意,映射不需要源属性和目标属性类型匹配。 如果没有(在这种情况下),则AutoMapper将使用单独的配置映射它们。

在我们的示例中,源属性类型为IList<TagViewModel> ,目标属性类型为ICollection<UserAndTagEntity> 忽略集合类型-AutoMapper知道如何转换它们。 它不知道并且需要指定的是元素类型之间的映射。 在我们的例子中,从TagViewModelUserAndTagEntity 因此,需要映射(2)。

里面的映射(2),我们只有部分之一,所以我们使用(3)指定-即我们映射TagViewModelTag的财产UserAndTagEntity 同样,类型不匹配,因此我们需要从TagViewModelTagEntity的映射(4)。

最终结果将是带有UserAndTags集合的UserEntity实例, UserAndTags填充了具有正确Tag属性的UserAndTagEntity实例。 然后,使用步骤(5)填充这些实例的User属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM