Lambda表达式

7

我能用Lambda表达式简化这个语句吗?

var project = from a in accounts
              from ap in a.AccountProjects
              where ap.AccountProjectID == accountProjectId
              select ap;
4个回答

4
var project = accounts.SelectMany(a => a.AccountProjects)
                      .Where(x => x.AccountProjectID == accountProjectId);

无论这是否更简单,都是个人口味问题。

我认为多个from子句在概念上比隐式展开的SelectMany更简单,但无论如何,LINQ语法的整个重点不就是提供比这些链接方法更清晰的语法吗? - Joren
这两种方法在概念上是等价的。它们做的事情完全相同。它们是表达完全相同操作集的两种不同方式。正如我在我的答案中指出的那样,哪种方法更“简洁”或“简单”是一个品味问题。 - Mark

3
老实说,我觉得这看起来很清晰。在这种情况下,使用lambda可能不太易读,例如像Brandon在下面发布的内容。
(从Brandon的帖子中窃取)
var project = accounts.Select(a => a.AccountProjects)
                      .Where(x => x.AccountProjectID == accountProjectId);

就可读性而言,我认为使用几个循环比lambda解决方案更好,而且我认为你的解决方案比循环更好。


4
这取决于你的写法——在".Where"前添加一个换行符,这个Lambda表达式就变得相当易读了。 - Joel Coehoorn
1
我有点同意Ed的观点。你现在的代码已经非常易读,使用lambda表达式并没有真正简化任何内容。这可能只是个人偏好的问题。 - Brandon
1
即使有换行,对我来说它仍然不够易读,但我想这是一个主观的问题。我想重点是:它非常清晰,继续解决真正的问题吧! :) - Ed S.
1
此外,这个答案中的lambda表达式是不正确的,原因和Brandon的一样(你实际上承认你从他那里“偷”了它)。 - Mark
1
@Mark,我觉得你在一定程度上误解了他的帖子的意思。他并没有说要使用lambda表达式,并且给出了我的(错误的)答案作为解决方案,他只是建议从他现在的方式切换到lambda表达式不会提高可读性。(嗯,这取决于个人偏好) - Brandon
显示剩余4条评论

2
我同意Ed Swangren的观点。这段文字看起来简洁易读。
实际上,你的问题的答案取决于三个因素:
1. 你想要实现什么目标——更好的可读性?更好的性能?等等。 2. 'accounts'的类型 3. 结果集将如何被使用。
如果你想要更好的性能,并且'accounts'是一个列表,而结果集将很快被迭代或传递给另一个方法进行迭代,我会这样做:
List<Account> filteredAccounts = new List<Account>();
accounts.ForEach(a => { if (a.AccountProjectID == accountProjectId) filteredAccounts.Add(a); });

虽然这段代码不如你的LINQ语句易读,但我更喜欢使用这两行代码而不是accounts.Select......

而且这段代码肯定比较优化,性能也更好,我认为这点非常重要。


2
这样做与在LINQ查询上调用ToList()相比有什么好处? - Jon Skeet
这个问题并没有要求你进行优化,而是要求你简化它。当你说它“更好地优化了性能”时,你也做出了一个相当大的假设。你真的测试过吗?你有数据来支持你的假设吗? - Mark
  1. 你所谓的简化是个人品味问题。我认为我在之前的帖子中已经回答了这个问题。
  2. 当然我测试过了,否则我就不会发帖了。问题不在于在查询中调用ToList方法。一般来说,LINQ to Objects 比传统技术(例如使用foreach循环迭代)慢两倍以上。不相信?你可以轻松地进行微基准测试或者搜索一下。此处使用的ForEach扩展方法与Lambda表达式结合使用,甚至比foreach循环更具性能优势。相信我,我花了相当大的精力研究这些事情的成本。
- Alexander
顺便提一下,您也犯了与其他答案相同的错误。您的代码与 OP 的代码根本不等价。Account 没有 AccountProjectID 属性,它有一个名为 AccountProject 的属性,这是一个 IEnumerable<something>,其中 something 是具有 AccountProjectID 属性的类型。我确实同意您通常使用 LINQ 会更慢。 - Mark

0
accounts
    .SelectMany (
        a => AccountProjects, 
        (a, ct) => 
        new  
        {
            a = a, 
            ap = ap
        }
    )
    .Where (t => (t.ap.AccountProjectID == t.a.accountProjectId))
    .Select (t => t.ap)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接