我对下面的内容感到困惑。
我一直在我的项目中使用 LINQ,格式如下:
var query =
from obj_i in set1
join obj_j in set2 on
new {
JoinField1 = obj_i.SomeField1,
JoinField2 = obj_i.SomeField2,
JoinField3 = obj_i.SomeField3,
JoinField4 = obj_i.SomeField4
}
equals
new {
JoinField1 = obj_j.SomeOtherField1,
JoinField2 = obj_j.SomeOtherField2,
JoinField3 = obj_j.SomeOtherField3,
JoinField4 = obj_j.SomeOtherField4
}
但最近有人告诉我,下面也是编写 LINQ 查询的“另一种方式”。
var query =
from obj_i in set1
join obj_j in set2 on
obj_i.SomeField1 = obj_j.SomeOtherField1 and
obj_i.SomeField2 = obj_j.SomeOtherField2 and
obj_i.SomeField3 = obj_j.SomeOtherField3 and
obj_i.SomeField4 = obj_j.SomeOtherField4
据我了解,使用单个 =
是错误的(尤其是在 by ==
不适用的情况下,因为您需要使用 equals
,但也使用 and
是错误的,因为正确的关键字应该是 &&
如果您被允许在此使用除 equals
之外的任何内容案例。
我可以理解where子句中&&
和==
的用法,这使得上面的代码可以使用更加突出,因为它没有'甚至编译。
我错过了什么吗? 如果是这样,您能告诉我在哪里可以了解这种编写 LINQ 的替代方法吗?
最佳答案
But I was recently told that the below is also 'another way' of writing LINQ queries.
不,您显示的第二个语法不正确。试一试,您会发现它无法编译。
Linq 查询理解语法中的 join
子句被转换为对 Join
的调用扩展方法。例如,这个查询:
var query =
from x in a
join y in b
on x.Foo equals y.Bar
select Baz(x, y);
翻译成:
var query = a.Join(b, x => x.Foo, y => y.Foo, (x, y) => Baz(x, y));
所以可以看到equals
左右两部分分别对应Join
方法的不同参数:左边部分为第一个选择join key源,右侧部分选择第二个源的键。然后将这些键相互匹配以执行连接。这是重要的部分:on
子句没有指定自由形式的连接条件,它指定了如何在每一侧提取连接键。所以左右键选择器必须清楚地分开;您显示的第二个语法不起作用,因为无法为任何一个来源提取完整的关键信息:只能通过评估每个 (x, y)
的连接条件来执行连接,这是一个 O(n²)
操作而不是(大致)O(n)
操作。
但是,有时您需要比等值连接所能提供的更大的灵 active ;在这种情况下,您可以使用交叉连接并过滤结果:
var query =
from x in a
from y in b
where x.Foo == y.Bar
select Baz(x, y);
或者在你的情况下:
var query =
from obj_i in set1
from obj_j in set2
where obj_i.SomeField1 == obj_j.SomeOtherField1
&& obj_i.SomeField2 == obj_j.SomeOtherField2
&& obj_i.SomeField3 == obj_j.SomeOtherField3
&& obj_i.SomeField4 == obj_j.SomeOtherField4;
关于c# - LINQ C#的编写方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10680844/