Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

before/ after map can't work well with IQueryable projections #1415

Closed
ximenchuifeng opened this issue Jul 24, 2024 · 1 comment
Closed

before/ after map can't work well with IQueryable projections #1415

ximenchuifeng opened this issue Jul 24, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@ximenchuifeng
Copy link

Describe the bug
before/ after map can't work well with IQueryable projections

Declaration code

    [Mapper]
    public static partial class ProductMapper
    {
        private static partial ProductListItemResp ToListItemResp(Product product);

        [UserMapping(Default = true)]
        public static ProductListItemResp MapToListItemResp(Product product)
        {
            // before
            var resp = ToListItemResp(product);
            // after
            resp.MachineId = product.IdentifierConfig?.MachineId;
            resp.MachineName = product.IdentifierConfig?.Machine?.Name;
            resp.CommModuleId = product.IdentifierConfig?.Machine?.CommModuleId;
            resp.CommModuleName = product.IdentifierConfig?.Machine?.CommModule?.Name;

            return resp;
        }
        
        public static partial IQueryable<ProductListItemResp> ToListItemQueryableResp(this IQueryable<Product> product);
    }

Actual relevant generated code

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
        private static partial global::MixingX.Ultra.Dto.Product.Resp.ProductListItemResp ToListItemResp(global::MixingX.Ultra.Data.Entities.Product product)
        {
            var target = new global::MixingX.Ultra.Dto.Product.Resp.ProductListItemResp()
            {
                Id = product.Id,
                Name = product.Name,
            };
            target.Info = product.Info;
            target.IdentifierConfigId = product.IdentifierConfigId;
            target.IdentifierConfigName = product.IdentifierConfig?.Name;
            target.CreateAt = product.CreateAt;
            target.UpdateAt = product.UpdateAt;
            target.LastUpdaterName = product.LastUpdater?.Name;
            return target;
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
        public static partial global::System.Linq.IQueryable<global::MixingX.Ultra.Dto.Product.Resp.ProductListItemResp> ToListItemQueryableResp(this global::System.Linq.IQueryable<global::MixingX.Ultra.Data.Entities.Product> product)
        {
#nullable disable
            return System.Linq.Queryable.Select(product, x => new global::MixingX.Ultra.Dto.Product.Resp.ProductListItemResp()
            {
                Id = x.Id,
                Name = x.Name,
                Info = x.Info,
                IdentifierConfigId = x.IdentifierConfigId,
                IdentifierConfigName = x.IdentifierConfig != null ? x.IdentifierConfig.Name : default,
                CreateAt = x.CreateAt,
                UpdateAt = x.UpdateAt,
                LastUpdaterName = x.LastUpdater != null ? x.LastUpdater.Name : default,
            });
#nullable enable
        }

// see also https://mapperly.riok.app/docs/configuration/generated-source/

Expected relevant generated code

  JUST CALL THE  [UserMapping(Default = true)]   Product  TO ProductListItem  Conversion

Environment (please complete the following information):

  • Mapperly Version: [3.6.0.0]
  • Nullable reference types: [enabled]
  • .NET Version: [e.g. .NET 8.0.]
  • Target Framework: [e.g. .net8.0]
  • IDE: [ Rider 2024.1.4]
  • OS: [e.g. macOS 13.3]

Additional context
Nothing

@ximenchuifeng ximenchuifeng added the bug Something isn't working label Jul 24, 2024
@trejjam
Copy link
Contributor

trejjam commented Jul 30, 2024

You can rewrite your definition to make it "projection compatible":

 [Mapper]
 public static partial class ProductMapper
 {
        // one option
        [MapProperty([nameof(Product.IdentifierConfig), nameof(Product.IdentifierConfig.MachineId)], [nameof(ProductListItemResp.MachineId)])]
        // another option
        [MapPropertyFromSource(nameof(ProductListItemResp.MachineName), Use = nameof(MapMachineName))]
        // etc
        public static partial ProductListItemResp ToListItemResp(Product product);

        [UserMapping(Default = false)] // this prevents general Project => string mapping
        private static string MapMachineName(Product product) => product.IdentifierConfig?.Machine?.Name;
        
        public static partial IQueryable<ProductListItemResp> ToListItemQueryableResp(this IQueryable<Product> product);
}

Before and after mappings are not supported in projection (they can not be supported).

@latonz latonz closed this as not planned Won't fix, can't repro, duplicate, stale Aug 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants