C# LINQ Any()方法返回

C# LINQ Any()方法返回,c#,linq-to-entities,entity-framework-core,C#,Linq To Entities,Entity Framework Core,我有一个典型的深入应用程序 这是我的应用程序的层次结构 审计 有许多 发现 我有一个视图组件,其中包含一个LINQ查询,使用Any()方法从顶级审核集合一直向下,以获取所有具有任何发现的审核,其中任何一个发现有建议,其中任何一个建议缺少角色id为15或26的分配。如果rec中缺少一条或两条分配记录,则应将rec、finding、audit添加到模型中返回的audit集合中 我们认为它似乎在起作用。但是我们注意到,当审计中只有一个结果时,它不会添加到集合中。只有当审核有多个发现,并且其中一个发现有

我有一个典型的深入应用程序

这是我的应用程序的层次结构

审计
有许多
发现

我有一个视图组件,其中包含一个LINQ查询,使用Any()方法从顶级审核集合一直向下,以获取所有具有任何发现的审核,其中任何一个发现有建议,其中任何一个建议缺少角色id为15或26的分配。如果rec中缺少一条或两条分配记录,则应将rec、finding、audit添加到模型中返回的audit集合中

我们认为它似乎在起作用。但是我们注意到,当审计中只有一个结果时,它不会添加到集合中。只有当审核有多个发现,并且其中一个发现有一个rec缺少分配时,审核才会被错误地添加

这一foreach声明似乎对我有效:

        // Where audit has a recommendation without an assigned PO Authorizer
        //    OR without an assigned Responsible Manager (Rec Level).
        List<Audit> auditsToAssign = new List<Audit>();
        foreach (Audit audit in audits)
        {
            foreach (Finding finding in audit.Findings)
            {
                foreach (Recommendation rec in finding.Recommendations)
                {
                    if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
                            || !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
                        )
                    {
                        if (!auditsToAssign.Contains(rec.Finding.Audit))
                        {
                            auditsToAssign.Add(rec.Finding.Audit);
                        }
                    }
                }
            }
        }

我不能100%确定我是否遵循了您的描述,但请尝试以下方法:

        audits = audits.Where(a => 
                     a.Findings.Any(f => 
                         f.Recommendations.Any(r => 
                             !r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15 || asgn.AssignmentRoleId == 26))));

此外,Linq将比foreach更快,因为Any()方法在找到匹配项时将停止枚举,而foreach方法将继续枚举整个集合,即使它们在一开始就找到匹配项。阅读IMHO也更容易(尽管当你开始使用它时需要一段时间才能让你的Linq eye进入)。我不能100%确定我是否遵循了你的描述,但请尝试以下方法:

        audits = audits.Where(a => 
                     a.Findings.Any(f => 
                         f.Recommendations.Any(r => 
                             !r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15 || asgn.AssignmentRoleId == 26))));

此外,Linq将比foreach更快,因为Any()方法在找到匹配项时将停止枚举,而foreach方法将继续枚举整个集合,即使它们在一开始就找到匹配项。阅读IMHO也更容易(尽管当你开始使用它时,需要一段时间才能进入你的Linq眼界)。

我认为你可以更容易地反向操作(假设你参考了完整的作业表):


我认为你可以更容易地反向操作(假设你有一个完整作业表的参考):


您对
Findings.Count()>0&
f.Recommendations.Count()>0&
的约束是不必要的,因为
.Any()
子句将在内部处理
Count()=0
。这是一种常见的反模式,因为它可能会导致整个数据集的枚举知道它大于0。我发现foreach代码更具可读性,如果它正常工作,是否需要重构为linq查询?可能需要添加到foreach版本的唯一内容是一些nullchecking@Ctrl_Alt_Defeat这实际上取决于
审核的类型。如果它是
IQueryable
(正如
实体框架核心
标记所暗示的那样)并且不需要加载所有这些导航集合,那么执行单个SQL并加载更少数据的LINQ查询将更加高效。即使使用
Include
s,LINQ查询仍然更可取,因为它将完成服务器端的大部分过滤。您对
Findings.Count()>0&
f.Recommendations.Count()>0&
的约束是不必要的,因为
。Any()
子句将在内部处理
Count()=0
。这是一种常见的反模式,因为它可能会导致整个数据集的枚举知道它大于0。我发现foreach代码更具可读性,如果它正常工作,是否需要重构为linq查询?可能需要添加到foreach版本的唯一内容是一些nullchecking@Ctrl_Alt_Defeat这实际上取决于
审核的类型。如果它是
IQueryable
(正如
实体框架核心
标记所暗示的那样)并且不需要加载所有这些导航集合,那么执行单个SQL并加载更少数据的LINQ查询将更加高效。即使使用
Include
s,LINQ查询仍然更可取,因为它将完成服务器端的大部分过滤。任何()方法都将停止枚举的解释仅适用于LINQ to对象,但这里的情况并非如此(除非
entity framework core
标记错误)。但除此之外,对于OP要求,该查询似乎是正确的。Any()方法将停止枚举的解释仅适用于LINQ to对象,这里的情况并非如此(除非
entity framework core
标记错误)。但除此之外,这个查询似乎是符合OP要求的正确查询。这个看起来很有希望。这个看起来很有希望。
        // Where audit has a recommendation without an assigned PO Authorizer
        //    OR without an assigned Responsible Manager (Rec Level).
        List<Audit> auditsToAssign = new List<Audit>();
        foreach (Audit audit in audits)
        {
            foreach (Finding finding in audit.Findings)
            {
                foreach (Recommendation rec in finding.Recommendations)
                {
                    if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
                            || !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
                        )
                    {
                        if (!auditsToAssign.Contains(rec.Finding.Audit))
                        {
                            auditsToAssign.Add(rec.Finding.Audit);
                        }
                    }
                }
            }
        }
audits = audits.Where(a =>
            a.Findings.Count() > 0 &&
            a.Findings.Any(f =>
                f.Recommendations.Count() > 0 &&
                (
                !f.Recommendations.Any(r =>
                    r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)) ||
                !f.Recommendations.Any(r =>
                    r.Assignments.Any(asgn => asgn.AssignmentRoleId == 26))
                )
            )
        );
        audits = audits.Where(a => 
                     a.Findings.Any(f => 
                         f.Recommendations.Any(r => 
                             !r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15 || asgn.AssignmentRoleId == 26))));
var auditsToAssign = assignments.Where(asgn => asgn.AssignmentRoleId != 15 && asgn.AssignmentRoleId != 26)
                        .Select(asgn => asgn.Recommendation.Finding.Audit)
                        .Distinct();