LINQ Присоединиться к нескольким из статей
При написании запросов LINQ в С# я знаю, что могу выполнить объединение, используя ключевое слово join
. Но что делает следующее?
from c in Companies
from e in c.Employees
select e;
Книга LINQ Я говорю, что это тип соединения, но не подходящее соединение (которое использует ключевое слово join
). Итак, какой тип соединения это?
Ответы
Ответ 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);
}