mapping - rto - एक DTO को अनफ़्लैट करने के लिए AutoMapper का उपयोग करना




rto office up (5)

Sydneyos जवाब के अलावा और ट्रेवर डी कोएकोक टिप्पणी के अनुसार, दो तरह से मैपिंग इस तरह से संभव है

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

public class PersonViewModel
{
    public string Name { get; set; }
    public string AddressStreet { get; set; }
    public string AddressCity { get; set; }
    public string AddressState { get; set; }
}

ऑटोमैपर मैपिंग

Mapper.Initialize(cfg => cfg.RecognizePrefixes("Address"));
Mapper.CreateMap<Person, PersonViewModel>();
Mapper.CreateMap<PersonViewModel, Address>();
Mapper.CreateMap<PersonViewModel, Person>()
    .ForMember(dest => dest.Address, opt => opt.MapFrom( src => src )));

यदि आप NameOf वर्ग को लागू NameOf , तो आप उपसर्ग जादू स्ट्रिंग से छुटकारा पा सकते हैं

Mapper.Initialize(cfg => cfg.RecognizePrefixes(Nameof<Person>.Property(x => x.Address)));

EDIT: C # 6 में

Mapper.Initialize(cfg => cfg.RecognizePrefixes(nameof(Person.Address)));

मैं अपने DTO से अपने डोमेन ऑब्जेक्ट्स पर जाने में कुछ समय बचाने के लिए AutoMapper का उपयोग करने की कोशिश कर रहा हूं, लेकिन मुझे मैप को कॉन्फ़िगर करने में परेशानी हो रही है ताकि यह काम करे, और मुझे आश्चर्य हो रहा है कि क्या AutoMapper गलत टूल हो सकता है काम।

डोमेन ऑब्जेक्ट (एक इकाई और एक मान) के इस उदाहरण पर विचार करें:

public class Person
{
    public string Name { get; set; }
    public StreetAddress Address { get; set; }
}

public class StreetAddress
{
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

मेरा DTO (एक Linq-to-SQL ऑब्जेक्ट से) इस तरह मोटे तौर पर देख रहा है:

public class PersonDTO
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

मैं अपनी रिपॉजिटरी में ऐसा करने में सक्षम होना चाहता हूं:

return Mapper.Map<PersonDTO, Person>(result);

मैंने ऑटोमैपर को हर तरह से कॉन्फ़िगर करने की कोशिश की है जो मैं समझ सकता हूं, लेकिन मुझे जेनेरिक मिसिंग टाइप मैप कॉन्फ़िगरेशन या असमर्थित मैपिंग त्रुटि मिलती रहती है, जिसमें कोई विवरण नहीं है कि मुझे यह बताएं कि मैं कहां असफल रहा हूं।

मैंने कई अलग-अलग विन्यासों की कोशिश की है, लेकिन यहाँ कुछ हैं:

Mapper.CreateMap<PersonDTO, Person>()
    .ForMember(dest => dest.Address, opt => opt.MapFrom(Mapper.Map<Person, Domain.StreetAddress>));

तथा

Mapper.CreateMap<Person, Domain.Person>()
    .ForMember(dest => dest.Address.Address1, opt => opt.MapFrom(src => src.Address))
    .ForMember(dest => dest.Address.City, opt => opt.MapFrom(src => src.City))
    .ForMember(dest => dest.Address.State, opt => opt.MapFrom(src => src.State));

मैंने पढ़ा है कि AutoMapper के साथ समतल वस्तुओं को आसान है, लेकिन उन्हें unflattening आसान नहीं है ... या संभव भी नहीं है। क्या कोई मुझे बता सकता है कि क्या मैं असंभव को करने की कोशिश कर रहा हूं, और अगर नहीं तो मैं क्या कर रहा हूं?

ध्यान दें कि मेरी वास्तविक वस्तुएं थोड़ी अधिक जटिल हैं, इसलिए यह संभव है कि मैं उस जानकारी को छोड़ रहा हूं जो त्रुटि की कुंजी है ... अगर मैं जो देख रहा हूं वह सही है तो मैं अधिक जानकारी प्रदान कर सकता हूं या परीक्षण के लिए अपनी वस्तुओं को सरल बनाना शुरू कर सकता हूं ।


टिप्पणी पोस्ट नहीं की जा सकती, इसलिए उत्तर पोस्ट करना। मुझे लगता है कि AutoMapper कार्यान्वयन में कुछ बदलाव थे इसलिए जवाब https://.com/a/5154321/2164198 हैनस द्वारा प्रस्तावित अब अनिवार्य नहीं है। हालांकि इस तरह के परिदृश्य में इस्तेमाल किया जा सकता है कि एक और तरीका है - ResolveUsing :

Mapper.CreateMap<Person, Domain.Person>()
    .ForMember(dest => dest.Address, opt => opt.ResolveUsing( src => { return new Address() {Address1 = src.Address, City = src.City, State = src.State }; }))

मैं यह प्रयोग कर रहा हूं

public static void Unflatten<TSource, TDestination, TMember>(this IMemberConfigurationExpression<TSource, TDestination, TMember> opt)
{
    var prefix = opt.DestinationMember.Name;
    var memberProps = typeof(TMember).GetProperties();
    var props = typeof(TSource).GetProperties().Where(p => p.Name.StartsWith(prefix))
        .Select(sourceProp => new
        {
            SourceProp = sourceProp,
            MemberProp = memberProps.FirstOrDefault(memberProp => prefix + memberProp.Name == sourceProp.Name)
        })
        .Where(x => x.MemberProp != null);
    var parameter = Expression.Parameter(typeof(TSource));

    var bindings = props.Select(prop => Expression.Bind(prop.MemberProp, Expression.Property(parameter, prop.SourceProp)));
    var resolver = Expression.Lambda<Func<TSource, TMember>>(
        Expression.MemberInit(Expression.New(typeof(TMember)), bindings),
        parameter);

    opt.ResolveUsing(resolver.Compile());
}

विन्यास

new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Person, PersonDTO>();
    cfg.CreateMap<PersonDTO, Person>().ForMember(x => x.HomeAddress, opt => opt.Unflatten());
});

मॉडल के

public class Person
{
    public string Name { get; set; }
    public Address HomeAddress { get; set; }
}

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

AutoMapper समतल सम्मेलनों के बाद

public class PersonDTO
{
    public string Name { get; set; }
    public string HomeAddressLine1 { get; set; }
    public string HomeAddressLine2 { get; set; }
    public string HomeAddressCity { get; set; }
    public string HomeAddressState { get; set; }
    public string HomeAddressZipCode { get; set; }
}

शायद कई सुधार की जरूरत है लेकिन यह काम करता है ...


यह देर हो सकती है लेकिन आप इस तरह से ऑब्जेक्ट बनाने के लिए लैम्बडा एक्सप्रेशन का उपयोग करके इसे हल कर सकते हैं:

Mapper.CreateMap<Person, Domain.Person>()
        .ForMember(dest => dest.Address, opt => opt.MapFrom( src => { return new Address() {Address1 = src.Address, City = src.City, State = src.State }; }))

https://github.com/omuleanu/ValueInjecter उपयोग https://github.com/omuleanu/ValueInjecter , यह चपटा और अप्रभावित करता है, और आपको जो कुछ भी चाहिए, वह डाउनलोड में एक asp.net mvc नमूना एप्लिकेशन है जहां सभी सुविधाओं का प्रदर्शन किया जाता है (यूनिट परीक्षण भी)