MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.29k stars 327 forks source link

ProjectToType not working well with inheritance #589

Closed AzGhort closed 1 year ago

AzGhort commented 1 year ago

Hello,

I have a problem using ProjectToType with base-derived class inheritance. I have a config as follows:

            config
                .ForType<IPCamera, IpCameraDto>()
                .Map(m => m.Image, d => d.AvatarImage)
                .Map(m => m.IpAddress, d => d.IPAddress.ToString())
                .Include<AxisIPCamera, AxisIpCameraDto>()
                .Include<BaslerIPCamera, BaslerIpCameraDto>()
                .Include<BaslerGrabberIPCamera, BaslerGrabberIpCameraDto>()
                .Include<VirtualIpCamera, VirtualIpCameraDto>();

and I am mapping as follows:

IQueryable<IPCamera> queryable = ...;
queryable.ProjectToType<IPCameraDto>()

The result of map only contains instances of base class dto (IPCameraDto) rather than respective derived types. When mapping in-memory as follows:

List<IPCamera> cameras = new { .... };
var dtos = _mapper.Map<IPCameraDto>()

The resulting list correctly contains only derived types (AxisIpCameraDto, BaslerIpCameraDto, ...).

Am I doing something wrong? Is this desired behavior? Or is there a bug in ProjectToType method?

Thanks in advance

flobiber commented 1 year ago

I also have this behaviour and had expected it differently

andrerav commented 1 year ago

@AzGhort Try materializing your queryable before calling ProjectToType(). Let me know if the problem is still there :)

Edit: By that, I mean:

var result = queryable.ToList().ProjectToType<IPCameraDto>()
AzGhort commented 1 year ago

@andrerav thanks for the reply, that works, as it is pretty much the same as the code I posted - eg. mapping "in-memory":

List<IPCamera> cameras = new { .... }; var dtos = _mapper.Map<IPCameraDto>()

Is there a reason why it does not work directly on IQueryable? :)

Thanks again

andrerav commented 1 year ago

@AzGhort Difficult to tell without seeing the complete query call chain. There are various issues that can occur depending on how the query expression is built and translated (for example EF Core has some known cases that will lead to issues), as well as using async method when materializing the query.

AzGhort commented 1 year ago

Ok thanks for the replies!