Ef Core Table relationship include count Error

Viewed 213

I'm new to using .NET and EF Core. I cannot count the like table associated with the post table.

What I want to do is show the total number of likes on the post.

PostManager:

var posts = await _unitOfWork.Posts
                             .GetAllAsync(p => p.UserId == userId && 
                                               p.IsActive == true, 
                                          l => l.Likes.Count()); 

EfBaseRepository:

public async Task<IList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> predicate = null, params Expression<Func<TEntity, object>>[] includeProperties)
{
        IQueryable<TEntity> query = _context.Set<TEntity>();

        if (predicate != null)
        {
            query = query.Where(predicate);
        }

        if (includeProperties.Any())
        {
            foreach (var includeProperty in includeProperties)
            {
                query = query.Include(includeProperty);
            }
        }

        return await query.ToListAsync();
}

Error:

System.InvalidOperationException: The expression 'Convert(l.Likes.AsQueryable().Count(), Object)' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393.

2 Answers

If you are new to EF Core, do not create generic repository it is useless pattern and just increase complexity.

Correct and fastest query is:

var likesCount = await _context.Posts
   .Where(p => p.UserId == userId && p.IsActive == true)
   .SelectMany(p => p.Likes)
   .CountAsync(); 

do this instead. Basically, you want to achieve "Lazy Loading". In your "GetAllAsync" method, the "includeProperties" is expecting a property. In this case, the "Likes" property so it "l.Likes" not "l.Likes.Count()". You can do your count afterwards.

var posts = await _unitOfWork.Posts
                         .GetAllAsync(p => p.UserId == userId && 
                                           p.IsActive == true, 
                                      l => l.Likes).ToListAsync(); 
var likesCount = posts.Likes.Count();
Related