AutoMapper – Как сопоставить завернутый объект с помощью ConstructUsing

Я пытаюсь развернуть завернутый класс в плоский объект через AutoMapper.

Я рассмотрел похожие вопросы, такие как Сопоставление времени выполнения AutoMapper C# в зависимости от свойства объекта, но я хочу, чтобы производный тип отображался с помощью AutoMapper, я не хочу return new MyFlatObject() в моей конфигурации AutoMapper.

Все свойства должны быть сопоставлены через дочернее свойство Value, только IsDeleted имеет отношение к родительскому.

Что у меня есть на данный момент:

Ошибка:

Были найдены несопоставленные элементы. Просмотрите типы и члены ниже. Добавить собственное выражение сопоставления, игнорировать, добавить собственный преобразователь или измените тип источника/назначения. Если соответствующий конструктор отсутствует, добавьте no-arg ctor, добавьте необязательные аргументы или сопоставьте все параметры конструктора
=> MyObject -> MyFlatObject (список элементов назначения)

[TestClass]
public class AutoMappingTest
{
    public interface IMyObject { }

    public class DeletableWrapper
    {
        public bool IsDeleted { get; set; }
        public IMyObject Value { get; set; }
    }

    public class MyObject : IMyObject
    {
        public bool Foo { get; set; }
    }

    public class MyFlatObject
    {
        public bool IsDeleted { get; set; }
        public bool Foo { get; set; }
    }

    [TestMethod]
    public void MappingTest()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<DeletableWrapper, MyFlatObject>().ConstructUsing((src, ctx) => ctx.Mapper.Map<MyFlatObject>(src.Value))
                .ForMember(e => e.IsDeleted, opt => opt.MapFrom(s => s.IsDeleted));

            cfg.CreateMap<MyObject, MyFlatObject>();
        });

        config.AssertConfigurationIsValid();
    }
}

Вы уверены, что ваш код компилируется? Судя по тому, что я прочитал, переменная cfg отсутствует, объявленная в файле MapperConfiguration. Вы пытаетесь сопоставить DeletableWrapper с MyFlatObject?

Yong Shun 15.04.2024 02:39

Спасибо за замечание, что-то пошло не так, когда я пытался его отформатировать. Сейчас исправил. Да, я.

Red Riding Hood 15.04.2024 02:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Примечание: мое решение без ConstructUsing

Из config.AssertConfigurationIsValid он жалуется, что для члена IsDeleted в правиле отображения (класса) нет сопоставления (правила) из MyObject в MyFlatObject.

Вы можете применить Ignore(), поскольку в исходном коде нет сопоставления, и поэтому он не будет жаловаться.

Для выравнивания вы можете использовать IncludeMembers.

var config = new MapperConfiguration((cfg) => 
{
    cfg.CreateMap<AutoMappingTest.DeletableWrapper, AutoMappingTest.MyFlatObject>()
        .ForMember(dest => dest.IsDeleted, opt => opt.MapFrom(src => src.IsDeleted))
        .IncludeMembers(src => (AutoMappingTest.MyObject)src.Value);

    cfg.CreateMap<AutoMappingTest.MyObject, AutoMappingTest.MyFlatObject>()
        .ForMember(dest => dest.IsDeleted, opt => opt.Ignore());
});

По отзывам @Lucian, .ForMember можно опустить, поскольку AutoMapper автоматически сопоставит элементы, если у них одинаковые имена:

cfg.CreateMap<AutoMappingTest.DeletableWrapper, AutoMappingTest.MyFlatObject>()
    .IncludeMembers(src => (AutoMappingTest.MyObject)src.Value);
Демо @ .NET Fiddle
Yong Shun 15.04.2024 03:06

Знак MapFrom можно убрать.

Lucian Bargaoanu 15.04.2024 06:40

Другие вопросы по теме