Расширение AutoMapper и generi c MapFrom с использованием выражений - PullRequest
0 голосов
/ 25 марта 2020

Я делаю несколько сложное сопоставление между моделью и Dto, и я не нашел решений после долгих исследований.

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

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

Я использую AutoMapper для сопоставления между продуктом и Dto. Тем не менее, значение продукта не является напрямую тем, что я пытаюсь отобразить, но вместо этого оно соответствует метке «Код»

Мы используем этот код для поиска строки в другой модели с именем Метка

class Label 
{
    public string Code { get; set; }
    public string Value { get; set; }
}

Вызов мапперу выглядит следующим образом:

var labels = MyDbContext.Labels;
var products = MyDbContext.Products.ProjectTo<DTO>(_mapper.ConfigurationProvider, new { labels });

И маппер выглядит так:

IQueryable<Label> labels = null;
CreateMap<Product, Dto>()
   .ForMember(x => x.Name, m => m.MapFrom(y => labels.Where(l => l.Code == y.Name).FirstOrDefault().Value);

Это проектируется правильно и работает очень хорошо.

Однако я хотел бы изменить это, чтобы сделать его более обобщенным c, где мне нужно будет только указать, какое свойство модели я хочу, и оно будет автоматически отображать его с помощью меток. Примерно так:

IQueryable<Label> labels = null;
CreateMap<Product, Dto>()
   .ForLabelMember(x => x.Name, y => y.Name, labels);

Вот что я пробовал:

public static IMappingExpression<Product, Dto> ForLabelMember(this IMappingExpression<Product, DTO> map, Expression<Func<Dto, object>> selector, Expression<Func<Product, object>> dtoExpression, IQueryable<Entities.Common.Label> labels)
{
    var labelParameter = Expression.Parameter(typeof(Label), "l");
    var condition = Expression.Lambda<Func<Label, bool>>(
                Expression.Equal(
                    Expression.Property(labelParameter, "Code"),
                    dtoExpression.Body
                    ), labelParameter);
    Expression<Func<Product, string>> mappingExpression = z =>     labels.Where(condition).FirstOrDefault().Value;
    map.ForMember(selector, m => m.MapFrom(mappingExpression));
    return map;
}

Моя проблема в том, что я не знаю, как сказать autopper, что "mappingExpression" z, которые соответствуют к исходной модели Product - та же лямбда, что и в «dtoExpression».

Я попытался упростить это, чтобы найти реальную проблему, и вот суть проблемы:

Expression<Func<Label, bool>> condition = l => l.Code == z.Name;
Expression<Func<Product, string>> mappingExpression = z => labels.Where(condition).FirstOrDefault().Value;

Я не могу в выражении условия ссылаться на лямбду ("z") из модели Продукта.

Любая помощь в выполнении этой работы или любой другой альтернативы будет высоко оценена.

...