Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我想将这个foreach循环转换为LINQ语句_C#_Linq_Entity Framework - Fatal编程技术网

C# 我想将这个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

无论如何,我都不是linq的高手,但我通常不会遇到这种问题。我想将此foreach语句转换为LINQ语句:

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));