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

Support Select/Projection of an IQueryable #214

Closed
pwelter34 opened this issue Jan 8, 2023 · 3 comments · Fixed by #287
Closed

Support Select/Projection of an IQueryable #214

pwelter34 opened this issue Jan 8, 2023 · 3 comments · Fixed by #287
Assignees
Labels
enhancement New feature or request

Comments

@pwelter34
Copy link

pwelter34 commented Jan 8, 2023

Is your feature request related to a problem? Please describe.
AutoMapper supports ProjectTo(this IQueryable) for creating a select expression for EF or other querable providers. Honestly, after this project, its the last reason to use AutoMapper. If this project could create the needed extension method, that would be super useful.

Describe the solution you'd like

Original

[Mapper]
public static partial class CarMapper
{
    public static partial IQueryable<CarDto> ProjectToCarDto(this IQueryable<Car> source);
}

Generated

public static partial class CarMapper
{
    public static IQueryable<CarDto> ProjectToCarDto(this IQueryable<Car> source)
    {
        return source
            .Select<Car, CarDto>(original =>
                new CarDto
                {
                    Make = original.Make, 
                    Model = original.Model
                }
            );
    }
}

Additional context

https://docs.automapper.org/en/stable/Queryable-Extensions.html

@latonz
Copy link
Contributor

latonz commented Jan 9, 2023

This is something we would like to implement. However, this needs some effort.

Rel. #99

@latonz latonz added the enhancement New feature or request label Jan 9, 2023
@latonz latonz self-assigned this Jan 23, 2023
@latonz
Copy link
Contributor

latonz commented Jan 26, 2023

Idea on how this could work:

A partial method for the projection is defined in the mapper:

public static partial IQueryable<CarDto> ProjectToDto(this IQueryable<Car> q);

To manually configure properties, additional mapping methods are defined in the mapper as needed:

[MapProperty("Model.Name", "ModelName")]
public static partial CarDto ToDto(Car car);

Mapperly generates the implementation of the projection method based on the configurations on the other defined methods, if available.
The methods with the configurations are also implemented by Mapperly.
This generates more code than neccessairy,
but it is an approach to make queryable projection mappings configurable.

Complete example:

// classes
public class Car
{
    public int Id { set; get; }

    public Manufacturer Manufacturer { set; get; } = new();
}

public class Manufacturer
{
    public string Name { set; get; } = string.Empty;
}

public class CarDto
{
    public int Id { set; get; }
    
    public string Producer { set; get; } = string.Empty;
}

// mapper definition
[Mapper]
public static partial class CarMapper
{
    public static partial IQueryable<CarDto> ProjectToDto(this IQueryable<Car> q);

    [MapProperty("Manufacturer.Name", "Producer")]
    public static partial CarDto ToDto(Car car);
}

// generated mapper implementation
public partial class CarMapper
{
    public static partial IQueryable<CarDto> ProjectToDto(IQueryable<Car> q)
    {
        return System.Linq.Queryable.Select(q, x => new CarDto() { Id = x.Id, Producer = x.Manufacturer.Name });
    }

    public static partial CarDto ToDto(Car car)
    {
        var target = new CarDto();
        target.Id = car.Id;
        target.Producer = x.Manufacturer.Name;
        return target;
    }
}

@latonz
Copy link
Contributor

latonz commented Mar 23, 2023

A first preview of this is released in 2.8.0-next.1. Feel free to give it a try (docs available here). Any feedback is welcome 😊 Note that these API's are still in an early preview and could break again until 2.8.0 is released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants