c# - Join with Where 子句的查询和方法 (lambda) 语法的等效性

标签 c# .net entity-framework linq linq-to-entities

我简化的 LINQ Join 加上两个表的 Where 如下所示:

var join = context.Foo
  .Join(context.Bar,
    foo => new { foo.Year, foo.Month },
    bar => new { bar.Year, bar.Month },
    (foo, bar) => new { foo.Name, bar.Owner, foo.Year })
  .Where(anon => anon.Year == 2015).ToList();

或者,我可以使用以下我希望等效的语法:

var joinQuery = from foo in context.Foo
                join bar in context.Bar
                on new { foo.Year, foo.Month } equals new { bar.Year, bar.Month }
                where foo.Year == 2015
                select new { foo.Name, bar.Owner };
var join = joinQuery.ToList();

我想到并想知道的一个区别是命令的顺序。在 lambda-syntax 连接中,我将 foo.Year 属性添加到我的匿名返回类型中,这样我就可以在之后进行过滤,而在其他查询中我仍然可以使用 foo (和 bar 如果我愿意的话)在 where 子句中。如果我不想或不需要,我不需要在此处将字段 foo.Year 添加到我的返回类型。

不幸的是,我没有 ReSharper 或任何类似的东西可以将较低的语句转换为 lambda 语句以便我可以进行比较。

我实际上可以做的(并使上层语句在结构上与下层语句更相似)是在 Where(..)ToList()< 之间添加以下行在第一个:

.Select(anon => new { /* the properties I want */ })

但是,与第二条语句相比,这不只是添加了“多一个”匿名类型创建,还是我在这里弄错了?

简而言之:第二个语句的等效 Join 语法是什么?或者第一个加上添加的 Select 是否真的等价,也就是说,joinQuery 是否在内部产生相同的代码?

最佳答案

在一般情况下,您不能总是像编译器那样完全在查询理解语法和 lambda 语法之间进行转换。这是由于使用了 transparent identifiers .但是您可以解决这个问题并生成语义等同 lambda 语句。这就是 ReSharper 所做的。

无论如何,在你的情况下,你可以添加:

.Select(anon => new { /* the properties I want */ })

这将在每行实例化一个匿名类型,但它不会是“一个”,所以不用担心:表达式已转换为 SQL,所以 join 中的 new { foo.Year, foo.Month } 语句并没有真正实例化这些对象,它们只是被转换为 SQL。只有最后一个选择才会同时用于 SQL SELECT 列表,并在检索到行后用于对象水合。

关于c# - Join with Where 子句的查询和方法 (lambda) 语法的等效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28827113/

相关文章:

.net - 我可以将一个导航器编译的 XPathExpression 与另一导航器一起使用吗?

.net - IfxConnection 和线程可以相处吗?

c# - 无法从一种模型转换为另一种模型

c# - 按不同日期排序时选择要列出的值()

c# - 为 Visual Studio 导出/导入包

c# - 如何在 C# 中将此 SQL 转换为 LINQ?

c# - 输出未正确写入 CSV

c# - 在 PostSharp 中是否可以修改方法的单个参数的值?

c# - EntityFramework 和处理重复的主键/并发/竞争条件情况

c# - Entity Framework 7 创建 DbSet 的内存中实现