完整数据集而不是 Top 1000 EF Core
Posted
技术标签:
【中文标题】完整数据集而不是 Top 1000 EF Core【英文标题】:Full Dataset rather than Top 1000 EF Core 【发布时间】:2019-10-03 14:16:31 【问题描述】:我正在尝试从表中返回前 1000 行,但是使用 EF Core,我在 .Take(1000) 运行之前获取了完整的数据集。
API
[HttpGet("MyThing/id")]
public List<MyObj> ItemsReport(long id)
response = new List<MyObj>();
response = _reporting.GetNewEntries(id);
return response;
报告
public virtual List<MyObj> GetNewEntries(long id)
var newEntries = new List<MyObj>();
var entries = _DbContext.ReportNewEntries
.OrderBy(a => long.Parse(a.Id))
.Where(a => long.Parse(a.Id) > id)
.Take(1000);
newEntries.AddRange(entries);
return newEntries;
DbContext
DbSet<MyObj> ReportNewEntries get; set;
我想要的查询是这样的:
SELECT TOP (1000) *
FROM dbo.ReportNewEntries
WHERE CONVERT(bigint, Id) > 0
ORDER BY CONVERT(bigint, Id)
根据 SQL 分析器,我当前的查询是:
SELECT * FROM dbo.ReportNewEntries
该表是单片的,所以我想一次访问 1000 行。对我犯了什么错误有什么建议吗?
【问题讨论】:
尚不清楚您的代码已经从表中仅返回 1000 行的问题是什么 试过var entries = _DbContext.ReportNewEntries.Take(1000).OrderBy(a => long.Parse(a.Id)).Where(a => long.Parse(a.Id) > id);
?
@AhmedYousif 问题清楚地表明问题不是代码返回的内容,而是它在下面运行的查询。
它不应该,因为在尝试解决它或调用 .ToList() ***.com/questions/2656576/… 之前该语句不会执行
@AhmedYousif - 但确实如此,我正在运行 sql profiler,而且确实如此。
【参考方案1】:
当您使用 List
时,您使用的是 Linq-To-Object,它适用于 IEnumerable
。
事实上,IEnumerable
会在应用 Take 之前首先将所有数据加载到内存中。
你要使用的是IQueryable
,也就是Linq-to-Sql。
因此,要么修改您的方法以返回 IQueryable<MyObj>
,要么使用 AsQueryable()
调用您的 Linq 链,如下所示:
var entries = _DbContext.ReportNewEntries.AsQueryable()
.OrderBy(a => long.Parse(a.Id)).Where(a => long.Parse(a.Id) > id).Take(1000);
【讨论】:
【参考方案2】:您使用的是什么数据库?什么版本的 .NetCore?什么数据库提供商?一些 db 提供程序可能在将一些 linq 语句转换为 sql 时遇到问题。在这种情况下,将在数据库中运行不同的查询(通常获取所有数据)并在内存中执行 linq。
【讨论】:
以上是关于完整数据集而不是 Top 1000 EF Core的主要内容,如果未能解决你的问题,请参考以下文章
EF Core 嵌套 Linq 选择导致 N + 1 个 SQL 查询
面向具有 EF6 和 Identity 的完整框架的 ASP.NET Core