实体框架核心数量没有最佳性能

Ren*_*ado 17 c# linq sql-server entity-framework-core

我需要通过某个过滤器获取记录数量.

从理论上讲这条指令:

_dbContext.People.Count (w => w.Type == 1);
Run Code Online (Sandbox Code Playgroud)

它应该生成SQL,如:

Select count (*)
from People
Where Type = 1
Run Code Online (Sandbox Code Playgroud)

但是,生成的SQL是:

Select Id, Name, Type, DateCreated, DateLastUpdate, Address
from People
Where Type = 1
Run Code Online (Sandbox Code Playgroud)

生成的查询在具有许多记录的数据库中运行需要更长的时间.

我需要生成第一个查询.

如果我这样做:

_dbContext.People.Count ();
Run Code Online (Sandbox Code Playgroud)

实体框架生成以下查询:

Select count (*)
from People
Run Code Online (Sandbox Code Playgroud)

..运行得非常快.

如何生成第二个查询将搜索条件传递给计数?

Iva*_*oev 13

这里没什么可回答的.如果您的ORM工具没有从简单的LINQ查询生成预期的SQL查询,那么您无法通过重写查询来让它执行此操作(并且您不应该首先执行此操作).

EF Core 在LINQ查询中具有混合客户端/数据库评估的概念,允许他们发布具有不完整/非常低效的查询处理的EF Core版本,就像您的情况一样.

摘自不在EF Core中的功能(注意单词not)和路线图:

改进了转换以使更多查询成功执行,在数据库中(而不是在内存中)评估更多逻辑.

不久,他们正计划改进查询处理,但我们不知道何时会发生这种程度和程度(记住混合模式允许他们考虑查询"工作").

那有什么选择呢?

  • 首先,远离EF Core,直到它变得非常有用.回到EF6,它没有这样的问题.
  • 如果您不能使用EF6,请使用最新的EF Core版本保持更新.

例如,在v1.0.1和v1.1.0中,您查询生成了预期的SQL(已测试),因此您可以简单地升级并且具体问题将消失.

但请注意,随着改进,新版本会引入错误/回归(正如您在此处看到的,EFCore为简单的LEFT OUTER连接返回了太多列),因此请自行承担风险(并再次考虑第一个选项,即哪一个适合你 :)


Raj*_*ali 6

尝试使用此lambda表达式更快地执行查询。

_dbContext.People.select(x=> x.id).Count();
Run Code Online (Sandbox Code Playgroud)

  • _dbContext.People.where(x = x.filterColumname ==输入参数).select(x => x.id).Count(); (5认同)

Pat*_*vay 6

尝试这个

(from x in _dbContext.People where x.Type == 1 select x).Count();
Run Code Online (Sandbox Code Playgroud)

或者你可以像这样执行异步版本:

await (from x in _dbContext.People where x.Type == 1 select x).CountAsync();
Run Code Online (Sandbox Code Playgroud)

如果这些不适合您,那么您至少可以通过执行以下操作来提高查询效率:

(from x in _dbContext.People where x.Type == 1 select x.Id).Count();
Run Code Online (Sandbox Code Playgroud)

或者

await (from x in _dbContext.People where x.Type == 1 select x.Id).CountAsync();
Run Code Online (Sandbox Code Playgroud)


The*_*heo 2

这是否得到你想要的:

_dbContext.People.Where(w => w.Type == 1).Count();
Run Code Online (Sandbox Code Playgroud)