Подтвердить что ты не робот

Linq 'в' путаницу ключевых слов

Я смотрел на запрос Linq для коллег, показанный ниже (запрос выполняется правильно):

from ea in EquipmentApplication
join erl in EquipmentRoutingLocation on ea.EquipmentID equals erl.EquipmentID into erlWithNulls

from erlAll in erlWithNulls.DefaultIfEmpty()
join rl in RoutingLocation on erlAll.RoutingLocationID equals rl.RoutingLocationID into rlWithNulls

from rlAll in rlWithNulls.DefaultIfEmpty()
where ea.Equipment.Master_Cell.Area.Unit.UnitID == 1160
select new { ea.Equipment, ea.ApplicationFriendlyName, rlAll }

Я смущен, почему это работает. Мое понимание (возможно, неверно) заключается в том, что ключевое слово "в" заканчивает текущую область/контекст (и любые созданные переменные теперь не входят в сферу действия) и создает новый. Если это так, почему переменная 'ea' остается в области видимости в последней части запроса?

4b9b3361

Ответ 1

При использовании с ключевым словом select into закончится область действия.
При использовании с ключевым словом join into добавляет переменную, содержащую все соответствующие элементы из соединения. (Это называется Group Join)

Ответ 2

"in" имеет два разных значения:

  • В предложении join он меняет перевод с join на GroupJoin. Это означает, что вместо получения одного результата для каждой пары вы получаете один результат для каждого элемента исходной последовательности, и этот результат содержит ключ и все результаты из другой последовательности в качестве группы. Подробнее см. Enumerable.GroupJoin
  • В select или group...by он становится продолжением , эффективно запуская новый запрос с результатами старого в новую переменную диапазона.

Ответ 3

Чтобы добавить к уже сказанному, я хотел бы продемонстрировать разницу в структуре объекта, созданной в противоположность:

var q = 
    from c in categories 
    join p in products on c equals p.Category into ps 
    select new { Category = c, Products = ps }; 

Создает граф объектов:

Category 1, Products:
  Product 1
  Product 2
Category 2, Products:
  Product 3
  Product 4

В этом случае q содержит только 2 элемента, две категории.

Без этого вы получаете более традиционное соединение, которое выравнивает отношения, создавая все возможные комбинации:

var q = 
    from c in categories 
    join p in products on c equals p.Category 
    select new { Category = c, Product = p }; 

Category 1, Product 1
Category 1, Product 2
Category 2, Product 3
Category 2, Product 4

Обратите внимание, что теперь q содержит 4 элемента.

Обновление, я думаю:

var q = 
    from c in categories 
    join p in products on c equals p.Category into ps 
    select new { Category = c, Products = ps.Select(x=> x.Id) };