mapperly icon indicating copy to clipboard operation
mapperly copied to clipboard

MapProperty with nullable reference types broken for IQueryable projections in v3.6.0

Open lschloetterer opened this issue 4 months ago • 0 comments

Describe the bug The MapProperty Attribute does not generate the appropriate code anymore for projections in the latest version. This behaviour applies when Nullable types are not enabled in the csproj file. It works up until v3.5.1 (see actual vs expected code below)

Declaration code

public class Car
{
  public int Id { get; set; }
  public string Manufacturer { get; set; }
}
public class CarDto
{
  public int Id { get; set; }
  public string Producer { get; set; }
}
[Mapper]
public static partial class CarMapper
{
  public static partial IQueryable<CarDto> ProjectToDto(this IQueryable<Car> q);

  [MapProperty(nameof(Car.Manufacturer), nameof(CarDto.Producer))]
  private static partial CarDto Map(Car car);
}

Actual relevant generated code

    public static partial class CarMapper
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
        public static partial global::System.Linq.IQueryable<global::MapperlyIQueryableBug.CarDto?>? ProjectToDto(this global::System.Linq.IQueryable<global::MapperlyIQueryableBug.Car?>? q)
        {
            if (q == null)
                return default;
#nullable disable
            return System.Linq.Queryable.Select(q, x => new global::MapperlyIQueryableBug.CarDto()
            {
                Id = x.Id,
            });
#nullable enable
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
        private static partial global::MapperlyIQueryableBug.CarDto? Map(global::MapperlyIQueryableBug.Car? car)
        {
            if (car == null)
                return default;
            var target = new global::MapperlyIQueryableBug.CarDto();
            target.Id = car.Id;
            target.Producer = car.Manufacturer;
            return target;
        }
    }

Expected relevant generated code

    public static partial class CarMapper
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.5.1.0")]
        public static partial global::System.Linq.IQueryable<global::MapperlyIQueryableBug.CarDto?>? ProjectToDto(this global::System.Linq.IQueryable<global::MapperlyIQueryableBug.Car?>? q)
        {
            if (q == null)
                return default;
#nullable disable
            return System.Linq.Queryable.Select(q, x => x == null ? default : new global::MapperlyIQueryableBug.CarDto()
            {
                Id = x.Id,
                Producer = x.Manufacturer,
            });
#nullable enable
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.5.1.0")]
        private static partial global::MapperlyIQueryableBug.CarDto? Map(global::MapperlyIQueryableBug.Car? car)
        {
            if (car == null)
                return default;
            var target = new global::MapperlyIQueryableBug.CarDto();
            target.Id = car.Id;
            target.Producer = car.Manufacturer;
            return target;
        }
    }

Environment (please complete the following information):

  • Mapperly Version: v3.6.0, also same behaviour in v4.0.0-next.4
  • Nullable reference types: disabled
  • .NET Version: .NET 8.0.202
  • Target Framework: .net8.0
  • Compiler Version: 4.9.0-3.24121.1 (a98c90d5)
  • C# Language Version: 12.0
  • IDE: Visual Studio v17.9.4
  • OS: Windows 11

Additional context

lschloetterer avatar Oct 01 '24 07:10 lschloetterer