Automapper : mapping issue with inheritance and abstract base class on collections with Entity Framework 4 Proxy Pocos

后端 未结 5 824
轻奢々
轻奢々 2020-12-07 20:23

I am having an issue using AutoMapper (which is an excellent technology) to map a business object to a DTO where I have inheritance off of an abstract base class within a co

相关标签:
5条回答
  • 2020-12-07 21:16

    I also tried Olivier's example and got the same StackOverflow errors. I also tried subkamran's solution but not luck there as I am not using a base class from the entity model code generation. Automapper still blows up. Until I find a better solution, I just set the Context to not create Proxies when I create a Context object.

    model.Configuration.ProxyCreationEnabled = false; 
    model.Configuration.LazyLoadingEnabled = true; 
    

    I would also like to see an answer to the problem perhaps using something build into Automapper...

    UPDATE: The Pre-release of Automapper corrects this issue and allows for the mapping to cover a DynamicProxy with no extra configuration.

    The release this works in is 2.2.1

    0 讨论(0)
  • 2020-12-07 21:21

    This answer comes 'a bit' late as I've just faced the same issue with EF4 POCO proxies.

    I solved it using a custom converter that calls Mapper.DynamicMap<TDestination>(object source) to invoke the runtime type conversion, rather than the .Include<TOtherSource, TOtherDestinatio>().

    It works fine for me.

    In your case you would define the following converter:

    class PaymentConverter : ITypeConverter<Payment, DtoPayment> {
        public DtoPayment Convert( ResolutionContext context ) {
            return Mapper.DynamicMap<DtoPayment>( context.SourceValue );
        }
    }
    

    And then:

    Mapper.CreateMap<Payment, DtoPayment>().ConvertUsing<PaymentConverter>();
    Mapper.CreateMap<CashPayment, DtoCashPayment>();
    Mapper.CreateMap<CreditCardPayment, DtoCreditCardPayment>();
    
    0 讨论(0)
  • 2020-12-07 21:22

    I ran into the same issue with Entity Framework proxies, but didn't want to switch to a pre-release version of AutoMapper. I found a simple if slightly ugly work around for version 2.2.0. I was trying to go from a DTO to an existing EF proxy object, and was getting errors about missing a mapping for the ugly proxy class name. My solution was to use an overload the specified the actual concrete types that I'd manually mapped:

    Mapper.Map(dtoSource, entityDest, typeof(DtoClass), typeof(ConcreteEntityClass));
    
    0 讨论(0)
  • 2020-12-07 21:22

    I've just faced the same problem with mapping dynamic EF proxies to ViewModels in MVC application.

    I found an easy solution using Mapper.DynamicMap() for this problem. Here is my code:

    Converting from Dynamic proxy to ViewModel class:

    // dynamic proxy instance
    WebService webService = _repWebService.GetAll().SingleOrDefault(x => x.Id == id);
    
    //mapping
    FirstStepWebServiceModel model = Mapper.DynamicMap<FirstStepWebServiceModel>(webService);
    

    Converting from ViewModel class to EF Dynamic Proxy:

    [HttpPost]
    public ActionResult FirstStep(FirstStepWebServiceModel input)
    {
        // getting the dynamic proxy from database
        WebService webService = _repWebService.GetAll().Single(x => x.Id == input.WebServiceId);
    
        // mapping the input ViewModel class to the Dynamic Proxy entity
        Mapper.DynamicMap(input, webService);
    }
    

    Hope this example help you

    0 讨论(0)
  • 2020-12-07 21:27

    Building on Olivier's response, I could not get his to work in my context... it kept going in an infinite loop and threw a StackOverflowException.

    In this example, AbstractClass is my base class and AbstractViewModel is my base view model (not marked as abstract mind you).

    However, I did get it to work using this hackish looking converter:

        public class ProxyConverter<TSource, TDestination> : ITypeConverter<TSource, TDestination>
            where TSource : class
            where TDestination : class
        {
            public TDestination Convert(ResolutionContext context)
            {
                // Get dynamic proxy base type
                var baseType = context.SourceValue.GetType().BaseType;
    
                // Return regular map if base type == Abstract base type
                if (baseType == typeof(TSource))
                    baseType = context.SourceValue.GetType();
    
                // Look up map for base type
                var destType = (from maps in Mapper.GetAllTypeMaps()
                               where maps.SourceType == baseType
                               select maps).FirstOrDefault().DestinationType;
    
                return Mapper.DynamicMap(context.SourceValue, baseType, destType) as TDestination;
            }
        }
    
        // Usage
    
        Mapper.CreateMap<AbstractClass, AbstractViewModel>()
            .ConvertUsing(new ProxyConverter<AbstractClass, AbstractViewModel>());
    

    So, a DerivedClassA will map normally, but a DynamicProxy_xxx will also map properly as this code inspects its base type (DerivedClassA).

    Please, please, please show me that I don't have to do this crazy lookup crap. I don't know enough AutoMapper to fix Olivier's answer properly.

    0 讨论(0)
提交回复
热议问题