具有新的多语言映射的投影或自定义值解析器

时间:2018-07-24 12:43:58

标签: asp.net-core automapper aspnetboilerplate

我正在使用最新版本的ASP.Net Boilerplate(版本3.7.2)。我目前正在使用新的多语言实体。

我对于将一个实体自动映射到Dto遇到问题,因为它不仅需要多语言方面,而且还需要其中一个属性的投影/自定义解析器。

到目前为止,所有映射均已正常工作。我遵循了ASP.NET Boilerplate Documentation

上的文档
[Table("CategoryItems")]
public class CategoryItem : BaseClass, IMultiLingualEntity<CategoryItemTranslation>
{
    /// <summary>
    /// Gets or Sets the Category Item Display Order
    /// </summary>
    public int DisplayOrder { get; set; }

    /// <summary>
    /// Gets or Sets Catalog Categories
    /// </summary>
    public virtual ICollection<CatalogItem> CatalogItems { get; set; } = new HashSet<CatalogItem>();

    ...

    /// <summary>
    /// Gets or Sets all the Entity Translations
    /// </summary>
    public virtual ICollection<CategoryItemTranslation> Translations { get; set; } = new HashSet<CategoryItemTranslation>();
}


[Table("CategoryItemTranslations")]
public class CategoryItemTranslation : IEntityTranslation<CategoryItem>
{
    /// <summary>
    /// Get or Set Category Item Name
    /// </summary>
    public string CategoryItemName { get; set; }

    /// <summary>
    /// Gets or Sets Link to Category Item
    /// </summary>
    public CategoryItem Core { get; set; }

    /// <summary>
    /// Gets or Sets Link to Core Id
    /// </summary>
    public int CoreId { get; set; }

    /// <summary>
    /// Gets or Sets the Language
    /// </summary>
    public string Language { get; set; }
}


public class ReadCategoryItemFilterDto : PhantomEntityDto
{
    public string CategoryItemName { get; set; }

    ...

    public int ItemCount { get; set; }

    ...
}

在ApplicationModule类的Initialize中使用Create MultiLingual Map代码:

cfg.CreateMultiLingualMap<CategoryItem, CategoryItemTranslation, ReadCategoryItemFilterDto>(new MultiLingualMapContext(IocManager.Resolve<ISettingManager>()));

翻译实体中的CategoryItemName正确映射到ReadCategoryItemFilterDto上的CategoryItemName。

现在,我需要将CatalogItems Count映射到Dto上的ItemCount。

我尝试添加到映射配置器:

cfg.CreateMap<CategoryItem, ReadCategoryItemFilterDto>()
    .ForMember(dest => dest.ItemCount, opts => opts.MapFrom(src => src.CatalogItems.Count));

cfg.CreateMap<CategoryItem, ReadCategoryItemFilterDto>()
    .ForMember(dest => dest.ItemCount, opts => opts.ResolveUsing(new CatalogItemFilterCountResolver()));

使用

public class CatalogItemFilterCountResolver : IValueResolver<CategoryItem, ReadCategoryItemFilterDto, int>
{
    public int Resolve(CategoryItem source, ReadCategoryItemFilterDto destination, int m, ResolutionContext context)
    {
        return source.CatalogItems.Count;
    }
}

如果我在CreateMultiLingualMap之前添加此映射,则CatalogItemName正确映射,但ItemCount失败。 如果我将Projection或Resolver放在CreateMultiLingualMap之后,则ItemCount可以正确映射,但CatalogItemName不能映射。

如何创建地图配置文件以允许同时映射两个属性?

谢谢。

2 个答案:

答案 0 :(得分:1)

对于您的情况,您不需要使用扩展名CreateMultiLingualMap。 您可以创建包含多语言映射的自己的映射定义。

就是这样完成的;

configuration.CreateMap<CategoryItem, ReadCategoryItemFilterDto>()
    .BeforeMap((source, destination, context) =>
    {
        var translation = source.Translations.FirstOrDefault(pt => pt.Language == CultureInfo.CurrentUICulture.Name);
        if (translation != null)
        {
            context.Mapper.Map(translation, destination);
            return;
        }


        var multiLingualMapContext = new MultiLingualMapContext(IocManager.Instance.Resolve<ISettingManager>());
        var defaultLanguage = multiLingualMapContext.SettingManager.GetSettingValue(LocalizationSettingNames.DefaultLanguage);

        translation = source.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage);

        if (translation != null)
        {
            context.Mapper.Map(translation, destination);
            return;
        }

        translation = source.Translations.FirstOrDefault();
        if (translation != null)
        {
            context.Mapper.Map(translation, destination);
        }

    }).ForMember(dest => dest.ItemCount, opts => opts.MapFrom(src => src.CatalogItems.Count));

答案 1 :(得分:0)

https://aspnetboilerplate.com/Pages/Documents/Multi-Lingual-Entities#createmultilingualmap

configuration.CreateMultiLingualMap<CategoryItem, CategoryItemTranslation, ReadCategoryItemFilterDto>(context)
.EntityMap.ForMember(dest => dest.ItemCount, opt => opt.MapFrom(src => src.CatalogItems.Count));