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