LINQ:点表示法与查询表达式

时间:2009-03-10 13:01:03

标签: linq .net-3.5 lambda

我开始一般使用LINQ(到目前为止使用XML和toSQL)。我已经看到有时候有两种或更多种方法可以达到相同的效果。拿这个简单的例子,据我所知,两者都返回完全相同的东西:

SomeDataContext dc = new SomeDataContext();

var queue = from q in dc.SomeTable
        where q.SomeDate <= DateTime.Now && q.Locked != true
        orderby (q.Priority, q.TimeCreated)
        select q;

var queue2 = dc.SomeTable
        .Where( q => q.SomeDate <= DateTime.Now && q.Locked != true )
        .OrderBy(q => q.Priority)
        .ThenBy(q => q.TimeCreated);

除了我在语法中可能犯的任何错误或缺少参数或差异之外,我的想法是有两种表达同一事物的方法;我知道第一种方法有一些局限性,“点符号”更完整,但除此之外,还有其他优点吗?

5 个答案:

答案 0 :(得分:51)

“点”表示法通常称为Lambda语法。第一种表示法有许多名称,但我通常将其称为查询语法。

我在一个由10名开发人员组成的团队中工作,我们详细讨论了我们应该将其作为标准使用的问题。一般来说,经验丰富的(使用LINQ)开发人员迁移到Lambda语法,但有一些重要的例外。

Lambda更简洁,但执行多个表连接是一场噩梦。使用查询语法,联接更加清晰。另一方面,有许多LINQ操作只存在于Lambda语法中:Single(),First(),Count()等。

所以,使用你最满意的东西,并意识到当你获得经验时,你的偏好可能会改变。能够阅读两者都很有价值,肯定会出现两种情况都需要使用的情况。其他情况会使一种风格超过另一种风格。最后,它们都被翻译成相同的可执行代码。

答案 1 :(得分:28)

我根据具体情况使用哪种语法对我的查询更具可读性。

在可能的情况下,我尽量避免混合和匹配这两者,虽然有时它没关系(例如,如果在查询结束时只有一次调用First())。延迟执行意味着使用查询表达式并将结果分配给变量同样有效,然后使用点符号使用该变量:

var query = from x in y
            orderby z
            group x by x.Name into groups
            // etc
            select foo;

var page = query.Skip(50).Take(10);

正如其他人所说,查询表达式只是在没有查询表达式的情况下被翻译成“普通”C#3,所以这样做没有任何代价。

答案 2 :(得分:8)

嗯,'dot'符号可以短得多。取:

var result = from p in dc.Products
             where p.Id > 5
             select p;

或:

var result = dc.Products.Where(p => p.Id > 5);

我更喜欢后者,因为它更短,更易读。

答案 3 :(得分:3)

我发现Lambda符号更整洁,更简洁。我觉得很烦人,如果你在方法调用中有一个Lambda表达式 where ,你就无法在调试模式下动态修改代码......

答案 4 :(得分:2)

他们编译成相同的代码,或者首先将第一个代码翻译成第二个然后编译。

你是对的,区别在于第一版更干净但更有限。在第二种情况下,您可以使用已有的代理,例如:

Func<int, bool> isEven = i => i%2 == 0;
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine);