简体   繁体   中英

How efficient is a cross-join in Linq-to-SQL?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM