Что означает множественный из селекторов в запросе LINQ - PullRequest
2 голосов
/ 21 февраля 2012

Несколько раз я видел несколько предложений from в запросе LINQ, но не выяснил, как это соответствует оператору TSQL.

var r = from p in products
        from d in departments
        from c in something
        select p;

Что это делает?

Это переводит в SQL как SELECT * FROM products, departments, something?

Кроме того, select в этом случае всегда должен быть SelectMany. как я могу узнать, когда select на самом деле является SelectMany?

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Это будет переводиться в код концептуально так:

var r = products.SelectMany(p => departments, (p, d) = new { p, d })
                .SelectMany(z => something, (z, c) => new { z, c })
                .Select(zz => zz.z.p);

Обычно каждый from после первого добавляет дополнительный вызов к SelectMany. На самом деле, в этом случае компилятор заметит, что после последнего предложения from есть просто select, и он на самом деле переведет это:

var r = products.SelectMany(p => departments, (p, d) = new { p, d })
                .SelectMany(z => something, (z, c) => z.p);

... но я склонен сначала думать о «логической» форме.

Обратите внимание, что в этом случае вы не использовали более ранние переменные диапазона в предложениях from, но вы можете:

var query = from person in people
            from friend in person.Friends
            select person.Name + " is friends with " + friend.Name;
2 голосов
/ 21 февраля 2012

Как это соответствует оператору TSQL?

Зависит от того, как вы используете ваши предложения from.Если вы используете:

var query = from d in context.Departments
            from e in context.Employees
            select d;

Ваш запрос будет CROSS JOIN, поскольку нет никакой связи между используемым продуктом и отделом.Так что-то вроде:

SELECT d.* FROM Departments AS d
CROSS JOIN Employees AS e

Очевидно, вам следует избегать перекрестных соединений.Если вместо этого вы используете свойство навигации во втором from:

var query = from d in context.Departments
            from e in d.Employees
            select d;

, вы будете использовать либо INNER, либо LEFT JOIN (EF решит, какое из них использовать, основываясь на вашем отображении множественности в отношении).Так что-то вроде:

SELECT d.* FROM Departments AS d
LEFT OUTER JOIN Employees AS e ON d.Id = e.DepartmentId
0 голосов
/ 21 февраля 2012

В этом случае не имеет смысла использовать select (это не семантически правильно, вы должны использовать SelectMany)

...