Reputation: 109547
I know that if you use Linq-to-objects to perform a cross-join, the inner sequence is iterated once for each element of the outer sequence.
The following code demonstrates the multiple iteration of 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()");
}
}
}
My question is this:
If you do the same sort of query in Linq-to-SQL, will it be optimised to a SQL CROSS JOIN
? Or will it evaluate the inner sequence multiple times (or do some other thing)?
(I'm almost certain that it will be optimised, but after searching the 'net I have failed to find any conclusive documentation about this.)
[EDIT]
I just wanted to mention the reason I'm asking this question.
Resharper
normally warns you if you iterate over an IEnumerable twice, but it doesn't warn you if you use a nested from
to perform a cross-join (such as in my sample code above).
I wondered why it didn't warn you, and decided it was probably due to one of two reasons:
Either it was an oversight, or it didn't need to because multiple enumeration isn't a problem for nested from
because it gets turned into an efficient operation in Linq-to-SQL. I'm thinking it's for the latter reason.
Now you might wonder if Resharper
should still warn anyway because Linq-to-objects will enumerate the inner sequence multiple times - but I guess that's much less serious.
Also, I am never actually performing such cross-joins on a database (nor do I intend to), but I have used them in Linq-to-objects.
Upvotes: 1
Views: 908
Reputation: 39085
Linq-to-SQL translates the linq query to T-SQL that runs on the database side.
For example, if you write:
from i in myContext.Table1
from j in myContext.Table2
select new {i,j}
Linq-to-SQL will translate that to a T-SQL query similar to:
SELECT *
FROM Table1, Table2
and then it will serve the resulting anonymous type objects by iterating over the resultset just once.
Hope this makes sense.
Upvotes: 4