我知道,如果您使用 Linq-to-objects 执行交叉连接,则内部序列会针对外部序列的每个元素迭代一次。
以下代码演示了 的多次迭代ints2
:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main()
{
var ints1 = Ints1();
var ints2 = Ints2();
var test = from i in ints1
from j in ints2
select i*j;
foreach (var i in test)
Console.WriteLine(i);
}
private static IEnumerable<int> Ints1()
{
Console.WriteLine("Starting Ints1()");
for (int i = 0; i < 5; ++i)
yield return i;
Console.WriteLine("Ending Ints1()");
}
private static IEnumerable<int> Ints2()
{
Console.WriteLine("Starting Ints2()");
for (int i = 0; i < 5; ++i)
yield return i;
Console.WriteLine("Ending Ints2()");
}
}
}
我的问题是这样的:
如果您在 Linq-to-SQL 中执行相同类型的查询,它会优化为 SQLCROSS JOIN
吗?还是会多次评估内部序列(或做其他事情)?
(我几乎可以肯定它会被优化,但在搜索“网络”后,我没有找到任何关于此的结论性文档。)
[编辑]
我只是想提一下我问这个问题的原因。
Resharper
如果您迭代 IEnumerable 两次,通常会警告您,但如果您使用嵌套执行交叉连接(例如在我上面的示例代码中) ,它不会警告您。from
我想知道为什么它没有警告您,并认为这可能是由于以下两个原因之一:
要么是疏忽,要么不需要,因为多重枚举对于嵌套来说不是问题,from
因为它变成了 Linq-to-SQL 中的高效操作。我想是后一个原因。
现在您可能想知道是否Resharper
仍应发出警告,因为 Linq-to-objects将多次枚举内部序列 - 但我想这不那么严重。
此外,我实际上从未在数据库上执行过这样的交叉连接(我也不打算这样做),但我已经在 Linq-to-objects 中使用了它们。