EF Core 查询优化:我可以在 List<string> 上使用 Contains 吗?
Posted
技术标签:
【中文标题】EF Core 查询优化:我可以在 List<string> 上使用 Contains 吗?【英文标题】:EF Core query optimization: can I use Contains on List<string>? 【发布时间】:2021-02-20 04:36:42 【问题描述】:使用 EF Core + .NET 5.0 预览版 + Postgres。
我正在尝试查找带有某个标签的所有问题。
我有这个Question
类:
public class Question : IEntity
/// <summary>
/// auto index
/// </summary>
public int Id get; set;
public List<string> tags get; set;
//other properties
所以,我希望这段代码能做我想做的事:
var questions = _context.Questions
.Where(question => question.tags.Contains(tag) == true)
.AsQueryable();
return questions.AsAsyncEnumerable();
但是什么也没发生。我记录了 EF Core SQL 查询,它看起来像这样:
[22:15:30 INF] Entity Framework Core 3.1.9 initialized 'ApplicationContext' using provider
'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
[22:15:30 INF] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT q."Id", q."OwnerId", q.answer_count, q.bounty_amount, q.bounty_closes_date, q.closed_date,
q.closed_reason, q.content_license, q.creation_date, q.is_answered, q.last_activity_date,
q.last_edit_date, q.link, q.question_id, q.score, q.tags, q.title, q.view_count
FROM "Questions" AS q
WHERE (TRUE = FALSE) = TRUE
这个问题让我很困惑。
我用更简单的方式重写了代码:
var qResult = new List<Question>();
var quests = _context.Questions.AsQueryable();
foreach (var q in quests)
if (q.tags.Contains(tag))
qResult.Add(q);
这段代码有效,但我担心它不是优化查询,当我有更多问题时 - 我会失去记忆。
那么,如何创建优化查询?
附:完整代码:github repo
这是我的appsettings.Development.json
:
"Logging":
"LogLevel":
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,
"AllowedHosts": "*",
"ConnectionStrings":
"Questions": "Host=localhost;Port=5432;Database=questionsdb;Username=postgres;Password=password"
,
"Tags": [
"ef core",
"c#",
"asp.net core",
"asp.net core webapi"
]
P.S.:另一个变体:
var questions = _context.Questions.Where(question => question.tags.Contains(tag)).AsQueryable();
return questions.ToList();
[21:44:29 INF] Executed DbCommand (1ms) [Parameters=[], CommandType='Text',
CommandTimeout='30']
SELECT q."Id", q."OwnerId", q.answer_count, q.bounty_amount,
q.bounty_closes_date, q.closed_date, q.closed_reason, q.content_license,
q.creation_date, q.is_answered, q.last_activity_date, q.last_edit_date,
q.link, q.question_id, q.score, q.tags, q.title, q.view_count
FROM "Questions" AS q
WHERE TRUE = FALSE
【问题讨论】:
public List<string> tags
未映射到任何表或列 - 您不能使用它进行数据库查询
@Fabio 实际上是 is mapped to PostgreSQL array data type column 由其 EF Core 提供商提供。
【参考方案1】:
只需尝试将您的查询更改为
return _context.Questions
.Where(q => q.tags.Contains(tag))
.ToArrayAsync();
【讨论】:
但查询将是相同的(withot ==true),例如:WHERE TRUE = FALSE 试一试,请告诉我结果。 对不起,我没有阅读整篇文章,所以我再次更新我的答案。也许它看起来一样,但值得一试。没有人知道 lInq 编译器是如何工作的。以上是关于EF Core 查询优化:我可以在 List<string> 上使用 Contains 吗?的主要内容,如果未能解决你的问题,请参考以下文章