我是Joins的业余爱好者,但我正在尝试使用表达式链式语法而不是LINQ语句。我发现的大多数示例都使用了数组或类列表{List <class
&gt; };但没有任何数组列表{List <array
&gt; }
List<int[]> needHelp = new List<int[]>{
new int[3] { 10, 20, 50},
new int[3] { 10, 21, 53},
new int[3] { 10, 22, 55},
new int[3] { 11, 20, 60},
new int[3] { 11, 22, 51} };
List<int[]> ghosts = new List<int[]>{
new int[3] { 10, 45, 65},
new int[3] { 11, 34, 60} };
有效的LINQ“查询”语法是:
List<int[]> result = (from h in needHelp join g in ghosts on h[0] equals g[0]
where h[1] == 21 select g).ToList();
但是这个“方法”表达式链接语法对我不起作用:
List<int[]> result = needHelp.Join(ghosts, x=>x[0], y=>y[0], (x,y) => y ).Where(x => x[1] == 21).ToList();
对于那些感兴趣的人,我发现这个lambda表达式链可以打印出一个数组List,而不必使用两个foreach循环。
result.ForEach( x => { Array.ForEach(x, e => Console.Write(e + " ") ); Console.WriteLine();} );
好吧我认为我找到了自己的解决方案,而且是通过更改where子句的位置。但是,何时必须在加入之前到来而不是之后工作?我在帖子上看到如果这是一个数据库调用where类在“.Join”之前,那么它将在服务器而不是客户端上处理。我假设在加入之后尝试使用它是超出的数据范围,在这个例子中将是y(列表<int[]
&gt;鬼魂)。
答案 0 :(得分:1)
Join
和Where
一般不可互换。
如果你“大声”阅读你的表达链,它会读到这样的内容:首先让我ghosts
中的所有数组与needHelp
中的第一个元素匹配,然后选择那些第二个元素等于21 的数组。
因此,在Join
之后,您只剩下来自ghosts
列表的数组。您的WHERE子句则不返回任何内容,因为ghosts
中的任何内容都没有第二个元素等于21.您正在needHelp
列表中检查它。
我建议您切换Join
和Where
:
List<int[]> result = needHelp.Where(x => x[1] == 21).Join(ghosts, x=>x[0], y=>y[0], (x,y) => y ).ToList();
如果它是您的混淆源,请不要认为函数中的x
和y
变量意味着多个函数的任何内容。您的Where
来电与x
needHelp
有关,但这并不意味着x
函数中的Join
与needHelp
相关;它引用Where
的输出,它是来自ghosts
的元素。
答案 1 :(得分:0)
您的Join方法不是您提供的查询语法的翻译。
您的查询过滤了h[1]
(加入时为x[1]
),但您只选择y
(查询中为g
),以便后面的地方适用于错误的事情。
以下是您的查询的直接翻译:
List<int[]> result =
needHelp
.Join (ghosts, x => x[0], y => y[0], (x, y) => new { x, y })
.Where (anon => anon.x[1] == 21)
.Select (anon => anon.y)
.ToList ();
答案 2 :(得分:0)
与此查询语法等效的确切方法语法
from h in needHelp join g in ghosts on h[0] equals g[0]
where h[1] == 21
select g
是这样的:
needHelp.Join(ghosts, h => h[0], g => g[0], (h, g) => new { h, g })
.Where(x => x.h[1] == 21)
.Select(x => x.g);
查询语法使用所谓的“透明标识符”来隐藏那些中间匿名类型,这就是为什么更适合涉及连接的查询。
谈到连接以及一般情况下,IMO最好在加入之前应用过滤器,尤其是在LINQ to Objects中,因为数据库查询优化器无论如何都会重新排列过滤器和连接操作。因此,更好的查询(来自性能和内存分配)将是:
needHelp.Where(h => h[1] == 21).Join(ghosts, h => h[0], g => g[0], (h, g) => g);