Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

EF Core and ProjectToType eager loader and is ignoring include

Open kavatari opened this issue 3 years ago • 5 comments

Following the next example: when using ProjectToType on a queryable Mapster is eager loading the data "SomeOtherEntity" and ignores the "include take(1)".

class SomeEntity 
{
    private ICollection<SomeOtherEntity> MyList { get; set; }
}

class SomeOtherEntity
{
    private SomeEntity myEntity { get; set; }
}

class MyModel 
{
    private ICollection<SomeOtherEntity> MyList { get; set; }
}

class MyOtherModel
{
    private MyModel myEntity { get; set; }
}

await _dbContext.SomeEntity
    .AsNoTracking()
    .Where(x => x.IsActive == isActive)
    .Include(x => 
        x.SomeOtherEntity
            .OrderByDescending(p => p.Date)
            .Take(1))
    .ProjectToType<MyModel>()
    .ToListAsync(cancellationToken);

Mapping data this way: works fine!

var data = await _dbContext.SomeEntity
            .AsNoTracking()
            .Where(x => x.IsActive == isActive)
            .Include(x => 
                x.SomeOtherEntity
                    .OrderByDescending(p => p.Date)
                    .Take(1))
            .ToListAsync(cancellationToken);

        return data.Adapt<List<SomeModel>>();

kavatari avatar Aug 21 '22 17:08 kavatari

I have tried something similar and noticed that the OrderBy on the SomeOtherEntity is not being executed in the query either.

heidgert avatar Oct 18 '22 14:10 heidgert

I also have some issue when the intention not to include some lazy loading property but eventually it loaded when use ProjectToType.

jewijaya avatar Dec 07 '22 02:12 jewijaya

This is a problem I too just noticed today when I saw the SELECT statement being generated with joins and I didn't do the joins/includes myself and I know EF Core doesn't eager load either unless the entities are already being tracked.

I will assume fixing this for all the use cases of queryable will prove hard and I'm not sure a mapper should be even doing that. As an optional, opt-in (i.e. explicit) feature, maybe but definitely not by default.

brgrz avatar Aug 24 '23 06:08 brgrz

Can confirm that using ProjectToType<> will remove the include "where" etc. This is pretty serious as the code compiles and runs without any warning that this will happen.

Is this considered expected behaviour or a bug that could be fixed?

Keseven avatar Jan 13 '24 16:01 Keseven

Updated to the latest version of Mapster recently and some of my tests suddenly started failing. Even just simply mapping a table to an output with no other methods doesn't work now.

public async Task<List<TOutput>> GetAllAsync<TEntity, TOutput>() where TEntity : class
{ 
    return await _context.Set<TEntity>().ProjectToType<TOutput>().ToListAsync();
}

Even with this oversimplified use case, no matter how many records the table has, this always returns an empty list. But, as mentioned above, doing:

public async Task<List<TOutput>> GetAllAsync<TEntity, TOutput>() where TEntity : class
{ 
    var entities = await _context.Set<TEntity>().ToListAsync();
    return entities.Adapt<List<TOutput>>();
}

Works just fine, so there's definitely an issue with the ProjectToType<>() method.

DisturbedNeo avatar Feb 02 '24 10:02 DisturbedNeo