EF Core 2.1 group by with skip and take
EF Core 2.1 group by with skip and take
我目前 "paging" 通过具有许多字段 {Table1Id、Table1Label、IsActive、...} 的 IQueryable,并且在 PdcId 的 IQueryable 结果中可以有多个记录,如下所示:
var result = from a in _entities.table1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
where a.Valide == true
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
我尝试了这段代码,但是当我看到使用 sql 探查器在 sql 中生成的结果时,查询是 运行 不停!! (生成多个 sql 查询)。
var data = await result.Where(i => result.GroupBy(p => p.Table1Id)
.Select(t => t.Key)
.Skip(query.Page).Take(query.PageSize)
.Contains(i.Table1Id)).ToListAsync();
如果我想先按 Table1Id 分组,然后跳过并采用不同的 Table1Id,我该怎么做。
例如:如果我的结果有两条记录,一条最终是 #50,另一条是 51,如果我按 50 分页,我不会得到记录 51,我想要它。
这就是我所做的和为我工作的:
解决方案 1
var dataTable1 = (from a in _entities.table1
where a.Valide == true
select new {...}).Skip(query.Page).Take(query.PageSize);
var result = from a in dataTable1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
var data = await result.ToListAsync();
解决方案 2
var result = from a in _entities.table1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
where a.Valide == true
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
result = !string.IsNullOrWhiteSpace(query.Table3Label) ? result.Where(c => c.Table3Label.ToLower().Contains(query.Table3Label.ToLower())) : result;
var table1Ids = await result.OrderBy(p => p.Table1Id)
.Select(p => p.Table1Id).Distinct()
.Skip(query.Page).Take(query.PageSize)
.ToListAsync();
var data = await result.Where(p => table1Ids.Contains(p.Table1Id)).ToListAsync();
如果示例中指定的连接表中存在子句条件(搜索条件),则方案2更有用。
希望对大家有所帮助。
我目前 "paging" 通过具有许多字段 {Table1Id、Table1Label、IsActive、...} 的 IQueryable,并且在 PdcId 的 IQueryable 结果中可以有多个记录,如下所示:
var result = from a in _entities.table1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
where a.Valide == true
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
我尝试了这段代码,但是当我看到使用 sql 探查器在 sql 中生成的结果时,查询是 运行 不停!! (生成多个 sql 查询)。
var data = await result.Where(i => result.GroupBy(p => p.Table1Id)
.Select(t => t.Key)
.Skip(query.Page).Take(query.PageSize)
.Contains(i.Table1Id)).ToListAsync();
如果我想先按 Table1Id 分组,然后跳过并采用不同的 Table1Id,我该怎么做。
例如:如果我的结果有两条记录,一条最终是 #50,另一条是 51,如果我按 50 分页,我不会得到记录 51,我想要它。
这就是我所做的和为我工作的:
解决方案 1
var dataTable1 = (from a in _entities.table1
where a.Valide == true
select new {...}).Skip(query.Page).Take(query.PageSize);
var result = from a in dataTable1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
var data = await result.ToListAsync();
解决方案 2
var result = from a in _entities.table1
join b in _entities.table2 on new { a.Table1Id, a.Table1LevelId } equals new { Table1Id = b.Table2Id, Table1LevelId = b.Table2LevelId }
join c in _entities.Table3 on a.Table1Id equals c.Table1Id into cc from ccc in cc.DefaultIfEmpty()
where a.Valide == true
select new MeteringPointDetailModel
{
Table1Id = a.Table1Id,
Table1Label = a.Label,
IsActive = a.IsActive,
Table3Label = ccc.Label,
};
result = !string.IsNullOrWhiteSpace(query.Table3Label) ? result.Where(c => c.Table3Label.ToLower().Contains(query.Table3Label.ToLower())) : result;
var table1Ids = await result.OrderBy(p => p.Table1Id)
.Select(p => p.Table1Id).Distinct()
.Skip(query.Page).Take(query.PageSize)
.ToListAsync();
var data = await result.Where(p => table1Ids.Contains(p.Table1Id)).ToListAsync();
如果示例中指定的连接表中存在子句条件(搜索条件),则方案2更有用。
希望对大家有所帮助。