如何解决因怪异的错误而导致的错误,包括 [英] How to resolve error with enitiy freamwork include

查看:53
本文介绍了如何解决因怪异的错误而导致的错误,包括的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用.Net 5和Entity Freamwork Core编写应用程序.我有正在寻找一些数据的方法.看起来像这样:

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看起来像这样:

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

如何解决此错误?

推荐答案

答案很简单.EF Core不会在 Include 定义中调用自定义方法.可以,因为此方法不是IQueryable方法.

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());
}

这篇关于如何解决因怪异的错误而导致的错误,包括的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆