【问题标题】:EF Core query optimization: can I use Contains on List<string>?EF Core 查询优化:我可以在 List<string> 上使用 Contains 吗?
【发布时间】: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

【问题讨论】:

标签: c# entity-framework asp.net-web-api .net-core entity-framework-core


【解决方案1】:

只需尝试将您的查询更改为

        return   _context.Questions
                         .Where(q => q.tags.Contains(tag))
                         .ToArrayAsync();

【讨论】:

  • 但查询将是相同的(withot ==true),例如:WHERE TRUE = FALSE
  • 试一试,请告诉我结果。
  • 对不起,我没有阅读整篇文章,所以我再次更新我的答案。也许它看起来一样,但值得一试。没有人知道 lInq 编译器是如何工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 2022-01-14
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 2021-11-12
相关资源
最近更新 更多