Entity framework core 当我使用单独的IQueryable泛型方法时,实体框架核心为MySQL生成了错误的查询

Entity framework core 当我使用单独的IQueryable泛型方法时,实体框架核心为MySQL生成了错误的查询,entity-framework-core,Entity Framework Core,当实体框架核心扔掉我的include时,我面临一种奇怪的行为。 我需要制作一些通用方法来过滤和组合我的查询,这些方法必须接收一些参数和IQueryable筛选器子查询,并返回组合的IQueryable结果以供进一步组合。 我简化了我的代码,并举了一个例子,当你明白我的意思时: public IQueryable<Tuple<TResult, TFilter>> Method1<TResult, TFilter>(IQueryable<TFilter>

当实体框架核心扔掉我的include时,我面临一种奇怪的行为。 我需要制作一些通用方法来过滤和组合我的查询,这些方法必须接收一些参数和IQueryable筛选器子查询,并返回组合的IQueryable结果以供进一步组合。 我简化了我的代码,并举了一个例子,当你明白我的意思时:

public IQueryable<Tuple<TResult, TFilter>> Method1<TResult, TFilter>(IQueryable<TFilter> filters)
   where TResult : ResultEntity
   where TFilter : FilterEntity
{
    var q = from state in _dbContext.Set<TResult>()
            join f in filters on state.ID_Result equals f.ID
            where ....
            select new Tuple<TResult, TFilter>(state, f);
            
    return q;
}

public void GetResult(int pageIndex, int pageSize)
{
    IQueryable<Car> results = _dbContext.Cars.Include(x => x.Images);
    
    // 1) All right, it has the images
    var q1 = Method1<CarState, Car>(results).ToList();
    
    // 2) Wrong, there is no images. And SQL query doesn't contain any joins to Images table
    var q2 = Method1<CarState, Car>(results).Skip(pageIndex).Take(pageSize).ToList();
    
    // 3) Without the method and with anonymous type it's ok.
    var tmp = from state in _dbContext.Set<CarState>()
              join f in results on state.ID_Result equals f.ID
              where ....
              select new { state, f };
    var q3 = tmp.Skip(pageIndex).Take(pageSize).ToList();
}
publicIQueryable方法1(IQueryable过滤器)
其中TResult:结果性
其中t过滤器:过滤性
{
var q=来自_dbContext.Set()中的状态
在state.ID上的筛选器中加入f\u结果等于f.ID
哪里
选择新元组(state,f);
返回q;
}
public void GetResult(int pageIndex,int pageSize)
{
IQueryable results=\u dbContext.Cars.Include(x=>x.Images);
//1)好的,它有图像
var q1=Method1(results).ToList();
//2)错误,没有图像。SQL查询不包含任何图像表的连接
var q2=Method1(结果).Skip(页面索引).Take(页面大小).ToList();
//3)如果不使用该方法,并且使用匿名类型,则可以。
var tmp=来自_dbContext.Set()中的状态
在state.ID上的结果中加入f\u结果等于f.ID
哪里
选择新{state,f};
var q3=tmp.Skip(pageIndex).Take(pageSize.ToList();
}

我做错了什么?

如果以后要使用查询,请不要使用生成器方法或构造函数。这是因为LINQ转换器无法回溯字段以生成正确的SQL

查询的这一部分有问题

new Tuple<TResult, TFilter>(state, f);
新元组(state,f);
创建新类更好

公共类MTuple
{
公共T1项1{get;set;}
公共T2项2{get;set;}
}
并在方法中使用它们(类似于匿名类的用法)

publicIQueryable方法1(IQueryable过滤器)
其中TResult:结果性
其中t过滤器:过滤性
{
var q=来自_dbContext.Set()中的状态
在state.ID上的筛选器中加入f\u结果等于f.ID
哪里
选择新的MTuple
{
第1项=状态,
项目2=f
};
返回q;
}
建议


这些类可以由生成,也可以复制

谢谢!我尝试创建自己的类,而不是元组,结果是一样的。如何在没有查询链接和代码复制的情况下解决问题?我有几十个类似的问题,但我没有完全理解。但也许您正在寻找这样的用例。为了简化可重用方法的创建,我为LINQKit编写了PR。仍然没有合并,但您可以自己编译它-这是一个小库。
public class MTuple<T1, T2>
{
    public T1 Item1 { get; set; }
    public T2 Item2 { get; set; }
}
public IQueryable<MTuple<TResult, TFilter>> Method1<TResult, TFilter>(IQueryable<TFilter> filters)
   where TResult : ResultEntity
   where TFilter : FilterEntity
{
    var q = from state in _dbContext.Set<TResult>()
            join f in filters on state.ID_Result equals f.ID
            where ....
            select new MTuple<TResult, TFilter>
            {
               Item1 = state, 
               Item2 = f
            };
            
    return q;
}