Skip to content

Instantly share code, notes, and snippets.

@tboby
Last active April 29, 2019 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tboby/069c56a54b40dbea6d7651f79e90a9a1 to your computer and use it in GitHub Desktop.
Save tboby/069c56a54b40dbea6d7651f79e90a9a1 to your computer and use it in GitHub Desktop.
Automapper ignore execution plan
static void Main(string[] args)
{
Mapper.Initialize(cfg =>
{
cfg.AddProfiles(new Profile[] { new CaseProfile()});
});
var configuration = new MapperConfiguration(cfg => cfg.CreateMap<CaseView, Case>());
var executionPlan = configuration.BuildExecutionPlan(typeof(CaseView), typeof(Case));
// Compare execution plans
executionPlan.ToReadableString().Dump();
// I can't reproduce the error I'm seeing with EF proxies yet
// var caseView = new CaseView(){
// User = new UserView{
// UserID = 5
// },
// UserID = 5
// };
// var existingCase = new Case(){
// User = new UserChild(){ UserID = 1 }
// };
// var result = Mapper.Map<CaseView, Case>(caseView, existingCase);
// if (result.User.UserID == 5) {
// throw new Exception("Should not have mapped");
// }
}
public class UserView {
public int UserID {get; set;}
}
public class User {
public int UserID { get; set; }
}
public class UserChild : User {
}
public class Case
{
// 1: Works
// [IgnoreMap]
//
public virtual User User {get; set;}
public int? UserID {get; set;}
}
public class CaseView
{
public UserView User {get; set;}
public int? UserID {get; set;}
}
public class CaseProfile : Profile {
public CaseProfile()
{
CreateMap<CaseView, Case>()
// 2 doesn't work
// .ForMember(x => x.User, opts => opts.Ignore())
// 3 doesn't work
// .ForMember(x => x.User, opts => opts.MapFrom(src => (User)null))
.ForMember(x => x.UserID, opts => opts.MapFrom (src => src.User.UserID));
CreateMap<UserView, User>();
}
}
@tboby
Copy link
Author

tboby commented Apr 29, 2019

Execution plans:
Default (no ignores)

(src, dest, ctxt) =>
{
    UserQuery.Case typeMapDestination;
    return (src == null)
        ? null
        : {
            typeMapDestination = dest ?? new UserQuery.Case();
            try
            {
                var resolvedValue = ((src == null) || false) ? null : src.User;
                var propertyValue =
                {
                    UserQuery.User typeMapDestination;
                    return (resolvedValue == null)
                        ? null
                        : {
                            ctxt.ValidateMap(TypeMap);
                            typeMapDestination = ((dest == null) ? null : typeMapDestination.User) ?? new UserQuery.User();
                            try
                            {
                                var resolvedValue = ((resolvedValue == null) || false) ? default(int) : resolvedValue.UserID;
                                typeMapDestination.UserID = resolvedValue;
                            }
                            catch (Exception ex)
                            {
                                throw new AutoMapperMappingException(
                                    "Error mapping types.",
                                    ex,
                                    AutoMapper.TypePair,
                                    TypeMap,
                                    PropertyMap);

                                return default(int);
                            }

                            return typeMapDestination;
                        };
                };

                typeMapDestination.User = propertyValue;
            }
            catch (Exception ex)
            {
                throw new AutoMapperMappingException(
                    "Error mapping types.",
                    ex,
                    AutoMapper.TypePair,
                    TypeMap,
                    PropertyMap);

                return null;
            }
            try
            {
                var resolvedValue = ((src == null) || false) ? null : src.UserID;
                var propertyValue = (resolvedValue == null) ? null : (int?)resolvedValue.Value;
                typeMapDestination.UserID = propertyValue;
            }
            catch (Exception ex)
            {
                throw new AutoMapperMappingException(
                    "Error mapping types.",
                    ex,
                    AutoMapper.TypePair,
                    TypeMap,
                    PropertyMap);

                return null;
            }

            return typeMapDestination;
        };
}

1: Ignoremap attribute:

(src, dest, ctxt) =>
{
    UserQuery.Case typeMapDestination;
    return (src == null)
        ? null
        : {
            typeMapDestination = dest ?? new UserQuery.Case();
            try
            {
                var resolvedValue = ((src == null) || false) ? null : src.UserID;
                var propertyValue = (resolvedValue == null) ? null : (int?)resolvedValue.Value;
                typeMapDestination.UserID = propertyValue;
            }
            catch (Exception ex)
            {
                throw new AutoMapperMappingException(
                    "Error mapping types.",
                    ex,
                    AutoMapper.TypePair,
                    TypeMap,
                    PropertyMap);

                return null;
            }

            return typeMapDestination;
        };
}

2/3: Ignore fluent/Null value

(src, dest, ctxt) =>
{
    UserQuery.Case typeMapDestination;
    return (src == null)
        ? null
        : {
            typeMapDestination = dest ?? new UserQuery.Case();
            try
            {
                var resolvedValue = ((src == null) || false) ? null : src.User;
                var propertyValue =
                {
                    UserQuery.User typeMapDestination;
                    return (resolvedValue == null)
                        ? null
                        : {
                            ctxt.ValidateMap(TypeMap);
                            typeMapDestination = ((dest == null) ? null : typeMapDestination.User) ?? new UserQuery.User();
                            try
                            {
                                var resolvedValue = ((resolvedValue == null) || false) ? default(int) : resolvedValue.UserID;
                                typeMapDestination.UserID = resolvedValue;
                            }
                            catch (Exception ex)
                            {
                                throw new AutoMapperMappingException(
                                    "Error mapping types.",
                                    ex,
                                    AutoMapper.TypePair,
                                    TypeMap,
                                    PropertyMap);

                                return default(int);
                            }

                            return typeMapDestination;
                        };
                };

                typeMapDestination.User = propertyValue;
            }
            catch (Exception ex)
            {
                throw new AutoMapperMappingException(
                    "Error mapping types.",
                    ex,
                    AutoMapper.TypePair,
                    TypeMap,
                    PropertyMap);

                return null;
            }
            try
            {
                var resolvedValue = ((src == null) || false) ? null : src.UserID;
                var propertyValue = (resolvedValue == null) ? null : (int?)resolvedValue.Value;
                typeMapDestination.UserID = propertyValue;
            }
            catch (Exception ex)
            {
                throw new AutoMapperMappingException(
                    "Error mapping types.",
                    ex,
                    AutoMapper.TypePair,
                    TypeMap,
                    PropertyMap);

                return null;
            }

            return typeMapDestination;
        };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment