我简化的 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/