使用LINQ的.NET Core中多个IQueryable的查询性能

时间:2018-11-02 11:20:54

标签: sql .net entity-framework linq

我目前正在将BackEnd项目更新为.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; 

获得这些IQueryable后,我在另一个上下文中运行了一个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与其他上下文相比,条目最多(约50000)。

2 个答案:

答案 0 :(得分:2)

queryNames,queryDefaults和queryDescriptions都是查询而不是集合。您正在循环运行它们。尝试将它们加载到循环之外。

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

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

答案 1 :(得分:1)

一个人可以编写如下查询

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

您还可以使用如下所示的“ foreach”

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