How to resolve error with enitiy freamwork include

时光怂恿深爱的人放手 提交于 2021-01-29 21:52:35

问题


I write app using .Net 5 and Entity Freamwork Core. I have method that is looking for some data. It looks like this:

        public async Task<Result<List<Company>>> Search(string keyword, DateTime From, DateTime To, JobTitle jobTitle)
        {
            return Result.Ok(await _dataContext.Companies
                .Include(x => x.Employes
                    .WhereIf(From != default && To != default,
                        x => x.DateOfBirth >= From && x.DateOfBirth <= To && x.JobTitle == jobTitle))
                .WhereIf(!string.IsNullOrEmpty(keyword), 
                    x => x.Name.Contains(keyword))
                .ToListAsync());
        }

WhereIf looks like this:

    public static class LinqExtension
    {
        public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition, Expression<Func<TSource, bool>> predicate)
        {
            if (condition)
                return source.Where(predicate);

            return source;
        }

        public static IEnumerable<TSource> WhereIf<TSource>(this IEnumerable<TSource> source, bool condition, Func<TSource, bool> predicate)
        {
            if (condition)
                return source.Where(predicate);

            return source;
        }
    }

And when I use this method I got this error:

System.InvalidOperationException: The expression 'x.Employes.WhereIf(__p_0, x => (((x.DateOfBirth >= __From_1) AndAlso (x.DateOfBirth <= __To_2)) AndAlso (Convert(x.JobTitle, Int32) == Convert(__jobTitle_3, Int32))))' 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

How resolve this error?


回答1:


Answer is simple. EF Core do not invoke custom methods in Include definition. Which is ok, because this method is not IQueryable method.

So just rewrite your code:

public async Task<Result<List<Company>>> Search(string keyword, DateTime From, DateTime To, JobTitle jobTitle)
{
   IQueryable<Company> query = _dataContext.Companies;
   if (From != default && To != default)
      query = query.Include(x => x.Employes
                 .Where(x => x.DateOfBirth >= From && x.DateOfBirth <= To && x.JobTitle == jobTitle));
   else
      query = query.Include(x => x.Employes);

   query = query.WhereIf(!string.IsNullOrEmpty(keyword), x => x.Name.Contains(keyword));

   return Result.Ok(await query.ToListAsync());
}

Or you can use additional extension for includes:

public static class LinqExtension
{
    public static IIncludableQueryable<TEntity, IEnumerable<TProp>> IncludeFiltered<TEntity, TProp>(
        this IQueryable<TEntity> source, bool condition, 
        Expression<Func<TEntity, IEnumerable<TProp>>> selector, 
        Expression<Func<TProp, bool>> predicate) 
        where TEntity : class
    {
        if (condition)
        {
            var newBody = Expression.Call(typeof(Enumerable), "Where", new[] {typeof(TProp)}, 
                selector.Body,
                predicate);

            selector = Expression.Lambda<Func<TEntity, IEnumerable<TProp>>>(newBody, selector.Parameters);
        }

        return source.Include(selector);
    }
}
public async Task<Result<List<Company>>> Search(string keyword, DateTime From, DateTime To, JobTitle jobTitle)
{
   return Result.Ok(await _dataContext.Companies
      .IncludeFiltered(From != default && To != default, 
         x => x.Employes, x => x.DateOfBirth >= From && x.DateOfBirth <= To && x.JobTitle == jobTitle)
      .WhereIf(!string.IsNullOrEmpty(keyword), 
         x => x.Name.Contains(keyword))
      .ToListAsync());
}


来源:https://stackoverflow.com/questions/65106895/how-to-resolve-error-with-enitiy-freamwork-include

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!