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

LINQ Присоединиться к нескольким из статей

При написании запросов LINQ в С# я знаю, что могу выполнить объединение, используя ключевое слово join. Но что делает следующее?

from c in Companies
from e in c.Employees
select e;

Книга LINQ Я говорю, что это тип соединения, но не подходящее соединение (которое использует ключевое слово join). Итак, какой тип соединения это?

4b9b3361

Ответ 1

Несколько "из" утверждений считаются составными значениями linq. Они похожи на вложенные операторы foreach. На странице msdn представлен отличный пример здесь

  var scoreQuery = from student in students
                         from score in student.Scores
                            where score > 90
                            select new { Last = student.LastName, score };

это утверждение можно было бы переписать как:

SomeDupCollection<string, decimal> nameScore = new SomeDupCollection<string, float>();
foreach(Student curStudent in students)
{
   foreach(Score curScore in curStudent.scores)
   {
      if (curScore > 90)
      {
         nameScore.Add(curStudent.LastName, curScore);
      }
   }
}

Ответ 2

Это будет переведено в вызов SelectMany(). Это, по сути, перекрестное соединение.

Джон Скит рассказывает об этом в своем блоге, как часть серии Edulinq. (Прокрутите вниз до пункта "Вторичный" из ".)

Ответ 3

Код, который вы указали:

from c in company
from e in c.Employees
select e;

... создаст список каждого сотрудника для каждой компании в переменной company. Если сотрудник работает для двух компаний, они будут включены в список дважды.

Единственное "соединение", которое может произойти здесь, - это когда вы говорите c.Employees. В поддерживаемом SQL-провайдере это приведет к внутреннему соединению из таблицы company в таблицу Employee.

Однако конструкцию double- from часто используется для выполнения "объединения" вручную, например:

from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;

Это будет иметь такой же эффект, как и код, который вы опубликовали, с потенциальными незначительными различиями в зависимости от того, что содержит переменная employees. Это также было бы эквивалентно следующему join:

from c in companies
join e in employees
   on c.CompanyId equals e.CompanyId
select e;

Если вы хотите декартово произведение, вы можете просто удалить предложение where. (Чтобы все было в порядке, вы, вероятно, тоже захотите изменить select.)

from c in companies
from e in employees
select new {c, e};

Этот последний запрос предоставит вам все возможные комбинации компании и сотрудника.

Ответ 4

Весь первый набор объектов будет соединен со всем вторым набором объектов. Например, следующий тест пройдет...

    [TestMethod()]
    public void TestJoin()
    {
        var list1 = new List<Object1>();
        var list2 = new List<Object2>();

        list1.Add(new Object1 { Prop1 = 1, Prop2 = "2" });
        list1.Add(new Object1 { Prop1 = 4, Prop2 = "2av" });
        list1.Add(new Object1 { Prop1 = 5, Prop2 = "2gks" });

        list2.Add(new Object2 { Prop1 = 3, Prop2 = "wq" });
        list2.Add(new Object2 { Prop1 = 9, Prop2 = "sdf" });

        var list = (from l1 in list1
                    from l2 in list2
                    select l1).ToList();

        Assert.AreEqual(6, list.Count);

    }