{"record":{"id":"de0a2141aba1b1ca","repo":"LuckyPennySoftware/AutoMapper","slug":"createprojection-works-with-projectto-not-with-ma","errorCode":null,"errorMessage":"CreateProjection works with ProjectTo, not with Map.","messagePattern":"CreateProjection works with ProjectTo, not with Map\\.","errorType":"exception","errorClass":"AutoMapperConfigurationException","httpStatus":null,"severity":"error","filePath":"src/AutoMapper/TypeMap.cs","lineNumber":57,"sourceCode":"            }\n            sourceMembers.Clear();\n            var propertyType = destinationProperty.GetMemberType();\n            if (profile.MapDestinationPropertyToSource(SourceTypeDetails, destinationType, propertyType, destinationName, sourceMembers, isReverseMap))\n            {\n                AddPropertyMap(destinationProperty, propertyType, sourceMembers);\n            }\n        }\n    }\n    public string CheckRecord() => ConstructorMap?.Ctor is ConstructorInfo ctor && ctor.IsFamily && ctor.Has<CompilerGeneratedAttribute>() ?\n        \" When mapping to records, consider using only public constructors. See https://docs.automapper.io/en/latest/Construction.html.\" : null;\n    public Features<IRuntimeFeature> Features => Details.Features;\n    private TypeMapDetails Details => _details ??= new();\n    public bool HasDetails => _details != null;\n    public void CheckProjection()\n    {\n        if (Projection)\n        {\n            throw new AutoMapperConfigurationException(\"CreateProjection works with ProjectTo, not with Map.\", MissingMapException(Types));\n        }\n    }\n    public static Exception MissingMapException(TypePair types) => MissingMapException(types.SourceType, types.DestinationType);\n    public static Exception MissingMapException(Type sourceType, Type destinationType)\n        => new InvalidOperationException($\"Missing map from {sourceType} to {destinationType}. Create using CreateMap<{sourceType.Name}, {destinationType.Name}>.\");\n    public bool Projection { get; set; }\n    public LambdaExpression MapExpression { get; private set; }\n    public Expression Invoke(Expression source, Expression destination) =>\n        Expression.Invoke(MapExpression, ToType(source, SourceType), ToType(destination, DestinationType), ContextParameter);\n    internal bool CanConstructorMap() => Profile.ConstructorMappingEnabled && !DestinationType.IsAbstract &&\n        !CustomConstruction && !HasTypeConverter && DestinationConstructors.Length > 0;\n    public TypePair Types;\n    public ConstructorMap ConstructorMap { get; set; }\n    public TypeDetails SourceTypeDetails { get; private set; }\n    public TypeDetails DestinationTypeDetails { get; private set; }\n    public Type SourceType => Types.SourceType;\n    public Type DestinationType => Types.DestinationType;\n    public ProfileMap Profile { get; }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/LuckyPennySoftware/AutoMapper/blob/dfa6dd587c5854b4beee5934beb39ba6e9569b84/src/AutoMapper/TypeMap.cs#L39-L75","documentation":"A map created with CreateProjection<TSrc,TDest> has TypeMap.Projection = true and is compiled only as a LINQ expression for ProjectTo; it has no runtime Map strategy. TypeMap.CheckProjection throws AutoMapperConfigurationException (with the missing-map inner exception) the moment such a map is selected for an in-memory Map. The message states the rule directly.","triggerScenarios":"cfg.CreateProjection<A,B>() followed by mapper.Map<B>(anA). Also when an inheritance chain or Include pulls a projection-only map into an in-memory mapping path.","commonSituations":"Reusing a query/read-model DTO for command-side in-memory mapping; copy-pasting CreateProjection where CreateMap was intended; mixing ProjectTo query DTOs with Map-based handlers; inheritance base defined as a projection.","solutions":["Change CreateProjection<TSrc,TDest> to CreateMap<TSrc,TDest> (or add a separate CreateMap) when in-memory Map is also needed.","Keep the projection for EF queries and use ProjectTo exclusively for that DTO.","Split into two DTOs/maps: a query projection DTO (ProjectTo) and a command DTO (CreateMap).","If inheritance is involved, make the base map a CreateMap, not a CreateProjection."],"exampleFix":"// before\nvar config = new MapperConfiguration(c => c.CreateProjection<Order, OrderDto>());\nvar dto = mapper.Map<OrderDto>(order); // throws: projection not for Map\n\n// after\nvar config = new MapperConfiguration(c => c.CreateMap<Order, OrderDto>());\nvar dto = mapper.Map<OrderDto>(order);","handlingStrategy":"validation","validationCode":"var typeMap = mapper.ConfigurationProvider.FindTypeMapFor<TSource, TDestination>();\nif (typeMap is { Projection: true })\n{\n    throw new InvalidOperationException(\n        $\"{typeof(TSource)}->{typeof(TDestination)} is a projection; use ProjectTo, or switch to CreateMap.\");\n}\n\nvar dest = mapper.Map<TDestination>(source);","typeGuard":"static bool IsInMemoryMappable(IConfigurationProvider cfg, Type src, Type dst) =>\n    cfg.FindTypeMapFor(src, dst) is { } tm && !tm.Projection;","tryCatchPattern":"try { dest = mapper.Map<TDestination>(source); }\ncatch (AutoMapperConfigurationException ex) when (ex.Message.Contains(\"CreateProjection works with ProjectTo\"))\n{\n    // switch the map to CreateMap, or call ProjectTo instead, then retry\n}","preventionTips":["Use CreateProjection only for query/read DTOs served by ProjectTo; use CreateMap for anything mapped in memory.","Keep query DTOs and command DTOs separate so a projection is never reused for Map.","When inheriting, ensure base maps are CreateMap if any derived map is used in-memory."],"tags":["projection","configuration","projectto","createprojection"],"backgroundTag":null,"analyzedSha":"dfa6dd587c5854b4beee5934beb39ba6e9569b84","analyzedAt":"2026-08-13T19:56:33.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}