【问题标题】:Query Performance for multiple IQueryable in .NET Core with LINQ使用 LINQ 在 .NET Core 中查询多个 IQueryable 的性能
【发布时间】:2018-11-02 11:20:54
【问题描述】:

我目前正在将后端项目更新到 .NET Core,但我的 Linq 查询存在性能问题。

主要查询:

var queryTexts = from text in _repositoryContext.Text
                         where text.KeyName.StartsWith("ApplicationSettings.")
                         where text.Sprache.Equals("*")
                         select text;

var queryDescriptions = from text in queryTexts
                                where text.KeyName.EndsWith("$Descr")
                                select text;

var queryNames = from text in queryTexts
                         where !(text.KeyName.EndsWith("$Descr"))
                         select text;

var queryDefaults = from defaults in _repositoryContext.ApplicationSettingsDefaults
                            where defaults.Value != "*"
                            select defaults; 

获得这些 IQueryables 后,我在另一个上下文中运行一个 foreach 循环来构建我的 DTO 模型:

foreach (ApplicationSettings appl in _repositoryContext.ApplicationSettings)
{
  var applDefaults = queryDefaults.Where(c => c.KeyName.Equals(appl.KeyName)).ToArray();

  description = queryDescriptions.Where(d => d.KeyName.Equals("ApplicationSettings." + appl.KeyName + ".$Descr"))
                .FirstOrDefault()?
                .Text1 ?? "";

  var name = queryNames.Where(n => n.KeyName.Equals("ApplicationSettings." + appl.KeyName)).FirstOrDefault()?.Text1 ?? "";

  // Do some stuff with data and return DTO Model
}

在我的旧项目中,这部分从大约 0.45 秒开始执行,现在我大约有 5-6 秒..

我考虑过使用编译查询,但我发现这些不支持返回 IEnumerable。我也试图避免 Contains() 方法。但无论如何它并没有提高性能。

您能否简要了解一下我的查询,并可能重构或提供一些提示如何使其中一个查询更快?
需要注意的是,_repositoryContext.Text 与其他上下文相比,由于翻译的原因,条目最多(约 50 000)。

【问题讨论】:

    标签: sql .net entity-framework linq


    【解决方案1】:

    queryNames、queryDefaults 和 queryDescriptions 都是 queries 而不是集合。你正在循环运行它们。尝试在循环之外加载它们。

    例如:将 queryNames 加载到字典中:

    var queryNames = from text in queryTexts
                             where !(text.KeyName.EndsWith("$Descr"))
                             select text;
    var queryNamesByName = queryName.ToDictionary(n => n.KeyName);
    

    【讨论】:

    • 如果旧 EF 上的相同代码需要 0.5 秒,现在 5 - 6 秒,它仍然是 EF Core 团队的主要兴趣点(如果代码相同)...
    • 我也会尝试这个,只是将前四个查询更改为使用 ToArray() 方法,然后在进一步的实现中使用数组。已经将时间减少到大约 1,5 秒。代码:var queryDefaults = _repositoryContext.ApplicationSettingsDefaults.Where( d => d.Value != "*").ToArray();
    • 我仍然想知道是否可以使用编译查询?因为这些查询在项目中执行了很多
    • @Vladimir 旧代码是原始 sql,但由于可读性,我想使用 linq 更改它
    【解决方案2】:

    可以编写如下查询

    var Profile="developer"; 
    var LstUserName = alreadyUsed.Where(x => x.Profile==Profile).ToList();   
    

    你也可以像下面这样使用“foreach”

    lstUserNames.ForEach(x=>
                            {
                               //do your stuff
                            });
    

    【讨论】:

    • 谢谢,但这已经在答案标记的帖子中提到了
    猜你喜欢
    • 1970-01-01
    • 2021-02-22
    • 2021-05-03
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    相关资源
    最近更新 更多