C# 我想将这个foreach循环转换为LINQ语句
无论如何,我都不是linq的高手,但我通常不会遇到这种问题。我想将此foreach语句转换为LINQ语句:C# 我想将这个foreach循环转换为LINQ语句,c#,linq,entity-framework,C#,Linq,Entity Framework,无论如何,我都不是linq的高手,但我通常不会遇到这种问题。我想将此foreach语句转换为LINQ语句: var existingKeys = new List<int>(); foreach (var taskKey in request.Keys) { existingKeys.AddRange(_context.WebTaskGroups .Where(x => x.TaskGroupNameK
var existingKeys = new List<int>();
foreach (var taskKey in request.Keys)
{
existingKeys.AddRange(_context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
.Select(x => x.TaskGroupNameKey));
}
这显然返回了一个空白而不是列表。。。
这:
给了我一个“IEnumerable.那么我在这里缺少的秘密是什么?首先你不应该执行N个数据库查询。使用LINQ执行这些N个查询而不是
foreach
循环并不能解决这个核心问题
var existingKeys = request
.SelectMany(r => r.Keys)
.SelectMany(tk =>
_context.WebTaskGroups
.Where(x.TaskGroupNameKey == key && x.TaskKey == tk)
.Select(x => x.TaskGroupNameKey))
.ToList();
您需要重新定义查询的概念,以便只有一个查询可以获取所需的所有数据。在这种情况下,这意味着获取与密钥集合匹配的所有项,而不是尝试匹配单个密钥,然后执行其中的N个查询
var requestedKeys = request.Keys;
var existingKeys = _context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key &&
requestedKeys.Contains(x.TaskKey))
.Select(x => x.TaskGroupNameKey))
.ToList();
ForEach返回无效:
forceh:对列表的每个元素执行指定的操作
因此,要做的是对request.key列表中的每个项执行添加到现有key列表中的操作
例如:
request.Keys.ForEach(taskKey =>
existingKeys.AddRange(_context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
.Select(x => x.TaskGroupNameKey));
假设您在Visual Studio中,Resharper(一个代码质量插件)实际上,他非常擅长识别可以转换为LINQ语句的循环。将
IEnumerable
转换为IEnumerable
应该可以使用SelectMany
而不是第一个Select。基本上,您要执行N个查询,每个键一个查询。您不应该这样做;您应该对每个键执行一个查询获取您想要的所有项目。执行所有这些往返数据库的操作尤其有问题。@Robert为什么要花大量时间来尝试解决方案,而您知道您将要放弃这些工作并做一些完全不同的事情呢?@Robert您一开始做的事情已经成功了。它不像您没有一个有效的解决方案。使用LINQ尝试删除循环不会改变代码的语义,这纯粹是美学上的。将代码更改为执行一个查询而不是N实际上是一个语义更改。+1表示有关查询数的通知!那么在在查询中重新使用它?@Robert有些查询提供程序可以正常工作,而您不需要这样做,有些则不行,所以我这样做了,因为我不确定您使用的是什么查询提供程序。这可能是一个愚蠢的问题,但“查询提供程序”是指我正在使用的ORM吗?好的,知道了,我正在使用EF。
var existingKeys = _context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key && request.Keys.Contains(x.TaskKey))
.Select(x => x.TaskGroupNameKey)
.ToList();
var requestedKeys = request.Keys;
var existingKeys = _context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key &&
requestedKeys.Contains(x.TaskKey))
.Select(x => x.TaskGroupNameKey))
.ToList();
request.Keys.ForEach(taskKey =>
existingKeys.AddRange(_context.WebTaskGroups
.Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
.Select(x => x.TaskGroupNameKey));